Внутренние интерфейсы - разоблачение моего невежества - PullRequest
0 голосов
/ 17 марта 2009

Мне известны эти два вопроса, которые объясняют, почему у меня не может быть защищенного / частного метода в интерфейсе, что я пытаюсь решить, как для управления откуда мои методы вызываются кратко:

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

Потребители могут использовать IStateMachine по умолчанию или использовать свои собственные.

Мне было интересно, есть ли способ гарантировать, что методы Action_ вызываются только из IStateMachine, чтобы потребители не начали возиться с состоянием состояния. Я подозреваю, что нет никакого способа сделать это, но задавался вопросом, пропускаю ли я что-то. Я не гуру Дизайна Дизайна.

Ответы [ 3 ]

3 голосов
/ 17 марта 2009

Хм, вы можете «спрятать» методы 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 голосов
/ 17 марта 2009

Хотя у вас не может быть модификаторов доступа на интерфейсах, но есть один способ скрыть участников, но сделать их доступными для разработчиков 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() {}
}
0 голосов
/ 17 марта 2009

Я не уверен, что понимаю, что вы хотите сделать. Но для сокрытия вещей я обычно реализую интерфейсы явно. Если кому-то нужен доступ к некоторым вещам, а не к другим, вам также следует разделить интерфейс на две части или что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...