Pregunta

Soy consciente de estos two preguntas que explican por qué no puedo tener un método protegido / privado en una interfaz, lo que soy intentar resolver es cómo controlar desde donde se llaman mis métodos, brevemente:

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

Los consumidores pueden usar el IStateMachine predeterminado o rodar el suyo.

Me preguntaba si hay alguna manera de garantizar que los métodos Action_ solo se invoquen dentro de una máquina IStateMachine, para que los consumidores no comiencen a perder el tiempo con las cosas del estado. Sospecho que no hay forma de hacerlo, pero me pregunté si me estoy perdiendo algo. No soy un gurú de patrones de diseño.

¿Fue útil?

Solución

Si bien no puede tener modificadores de acceso en las interfaces, esta es una forma de ocultar los miembros y, sin embargo, hacerlos accesibles para los implementadores de 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() {}
}

Otros consejos

Hmm, lo que puedes hacer es 'ocultar' los métodos Action_ implementando esos métodos explícitamente.

Si hace esto, los usuarios solo pueden llamar a esos métodos cuando devuelven la clase a la interfaz. Sin embargo, no evitará que tengan la posibilidad de llamar a esos métodos, pero tal vez hará que sea menos obvio que es posible.

public class EditField : IEditField
{
    public EditField( IStateMachine stateMachine ) {}

    void IEditField.Action_Commit() {}

    void IEditField.Action_Undo() {}

}

Al implementar estos métodos como este, el usuario no podrá hacer esto:

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

Sin embargo, es posible llamar a esos métodos si hacen esto:

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

o

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

Pero, ¿no es una mejor solución / posible tener esos Commit & amp; ¿Deshacer métodos como parte de su IStateMachine?

Y, si no puede modificar el diseño para tener esos Commit & amp; ¿Deshacer métodos parte de IStateMachine, entonces tal vez pueda crear una clase abstracta en lugar de la interfaz IEditField?
En esa clase abstracta, puede proteger esos métodos Action_.

No estoy seguro de entender lo que quieres hacer. Pero para ocultar cosas, generalmente implemento interfaces explícitamente. Si alguien necesita acceso a algunas cosas y no a otras, probablemente también deba dividir la interfaz en dos o algo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top