内部接口——暴露我的无知

Posted

技术标签:

【中文标题】内部接口——暴露我的无知【英文标题】: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_ 方法,这样消费者就不会开始弄乱状态的东西。我怀疑没有办法做到这一点,但想知道我是否遗漏了什么。我不是设计模式大师。

【问题讨论】:

【参考方案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】:

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

【讨论】:

以上是关于内部接口——暴露我的无知的主要内容,如果未能解决你的问题,请参考以下文章

闭包以及暴露接口---学习笔记

通过接口方式调用服务里面的方法

暴露属性和 Kotlin 数据类的接口

通过dubbo暴露接口调用方法,及基于zookeeper的dubbo涉及配置文件

使用 ProGuard 混淆时暴露内部类

通过dubbo暴露接口调用方法,及基于zookeeper的dubbo涉及配置文件