【问题标题】:Force immutability and create instance in the interface declaration强制不变性并在接口声明中创建实例
【发布时间】:2017-08-27 09:51:21
【问题描述】:

我有一个接口,它的 API 只是 getter 方法,从而确保实现该接口的类在这方面是不可变的。
但是,如果我需要更新一些改变接口行为的东西,我将如何声明我的接口以便它创建具体类的新实例?
现在我有类似的东西:

    public interface Generator {  
      public int[] values();  
      public float[] indications();  
      //etc  
      public MyEnum type;  
    }  

    public class ConcreteClass implements Generator {  
      private ConcreteClass() {  
      }  
      public static ConcreteClass createInstance() {  

       }  
   }    

为了清楚起见,我省略了参数。
如何将createInstance 移动到界面?

【问题讨论】:

    标签: java api oop interface


    【解决方案1】:

    接口不是为实现而设计的。使用 Java 8,您可以使用默认方法,但接口知道实现类是个坏主意。接口应该保持抽象,不知道它的子类。

    如果ConcreteClass 是不可变的,则应记录它并确保每个具有副作用的方法不对当前对象应用任何修改,而是创建ConcreteClass 的新实例。

    例如,假设您要提供方法来更新values 字段,您可以在ConcreteClass 中提供此方法:

    public ConcreteClass withValues(int[] values){
       // copy all existing properties from the original to the copy but values
       ConcreteClass copy = new ConcreteClass(values, this.indications, this.type);    
       return copy;
    }
    

    如果您真的想从ConcreteClass 移出实例创建,您可以创建一个提供此服务的工厂。

    【讨论】:

    • 我正在考虑将createInstance() 作为接口声明的一部分移动是否是一种好的设计方法。我只会定义方法而不是实际的实现
    • 在接口中添加抽象方法来创建新实例假设接口知道约束实现(例如必填字段),这也不是一个好主意,因为它将接口耦合到执行。只有反过来才是正确的。
    • 那么当我说接口定义了不可变的东西时也不正确?因此,如果我添加一个 setter 并不重要?
    • 确实如此。接口不能自己定义。它可以被记录为设计为不可变的,但只有实现才能使具体类不可变。如果您想保持实现不可变,则不必强制添加 setter。在我的回答中,我展示了一种在调用副作用操作(例如 setter)时创建新实例的方法。
    • 问题是这适用于知道ConcreteClass 的类。但我的兴趣是所有只知道Generator 参考的用途
    猜你喜欢
    • 2011-02-15
    • 2018-08-09
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2013-07-07
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多