【问题标题】:Internal interfaces - exposing my ignorance内部接口——暴露我的无知
【发布时间】:2010-10-13 19:15:19
【问题描述】:

我知道thesetwo 的问题解释了为什么我不能在接口中使用受保护/私有方法,我正在努力解决的是如何控制从哪里 简要地调用了我的方法:

public class EditField : IEditField
{
    public EditField() {}
    public EditField(IStateMachine stateMachine) {}
    public void Action_Commit() {}
    public void Action_Undo() {}
}

消费者可以使用默认的 IStateMachine,或者自己滚动。

我想知道是否有任何方法可以确保仅从 IStateMachine 中调用 Action_ 方法,这样消费者就不会开始弄乱状态的东西。我怀疑没有办法做到这一点,但想知道我是否遗漏了什么。我不是设计模式大师。

【问题讨论】:

    标签: c# interface access-modifiers


    【解决方案1】:

    虽然您不能在接口上使用访问修饰符,但这里有一种方法可以隐藏成员,同时让 IStateMachine 实现者可以访问它们。

    public interface IEditActions
    {
      void Action_Commit() {}
      void Action_Undo() {}
    }
    
    public interface IStateMachine
    {
      void Initialize(IEditActions editActions);
    }
    
    public class EditField : IEditField
    {
      private class EditActions : IEditActions
      {
        EditField _editField;
    
        public EditActions(EditField editField)
        {
          _editField = editField;
        }
    
        public void Action_Commit()
        {
          _editField.Action_Commit();
        }
        public void Action_Undo()
        {
          _editField.Action_Undo();
        }
      }
    
      public EditField() {}
      public EditField(IStateMachine stateMachine)
      {
        stateMachine.Initialize(new EditActions(this));
      }
    
      private void Action_Commit() {}
      private void Action_Undo() {}
    }
    

    【讨论】:

      【解决方案2】:

      嗯,您可以做的是通过显式实现这些方法来“隐藏”Action_ 方法。

      如果这样做,用户只能在将类转换回接口时调用这些方法。 然而,这不会阻止他们调用这些方法,但也许它会让它变得不那么明显。

      public class EditField : IEditField
      {
          public EditField( IStateMachine stateMachine ) {}
      
          void IEditField.Action_Commit() {}
      
          void IEditField.Action_Undo() {}
      
      }
      

      通过像这样实现这些方法,用户将无法做到这一点:

      EditField ef = new EditField();
      ef.Action_Commit(); // compile-error
      

      但是,如果它们这样做,则可以调用这些方法:

      IEditField ef = new EditField();
      ef.Action_Commit();
      

      EditField ef = new EditField()
      ((IEditField)ef).Action_Commit();
      

      但是,将这些 Commit & Undo 方法作为 IStateMachine 的一部分不是更好的解决方案吗?

      而且,如果您不能修改设计以使这些 Commit 和 Undo 方法成为 IStateMachine 的一部分,那么也许您可以创建一个抽象类而不是 IEditField 接口?
      在那个抽象类中,您可以保护那些 Action_ 方法。

      【讨论】:

        【解决方案3】:

        我不确定我是否理解您想要做什么。但是为了隐藏东西,我通常会显式地实现接口。如果有人需要访问某些东西而不是其他东西,您还应该将界面分成两个或其他东西。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-28
          • 2020-01-31
          • 1970-01-01
          • 2020-02-21
          • 1970-01-01
          相关资源
          最近更新 更多