Java中的私有类数据设计模式

时间:2017-03-01 20:04:33

标签: java design-patterns

我正在阅读私有班级数据设计模式 here,并且我试图了解它能够真正实现的目标。

据我所知,私人类数据设计模式是一种旨在重现" readonly"属性甚至是类本身:while" private"属性是可见的,只能编辑到类本身,属性类中的属性"私有类数据"根本无法改变(即使偶然)。唯一的解决方案是在私有类数据中提供一个setter,尽管(至少在我看来)如果私有类数据具有属性的所有setter,那么我们可能已经打败了该模式的目的。

假设我的理解是正确的,这会导致一个问题:即使主类不能更改任何私有类数据属性,它也可以设置私有类数据本身的引用,用它填充它它想要改变的变量

换句话说,一个不关心的开发者可能会这样做:

public class MainData {
    int foo;
    int bar;
    public MainData(int foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    } 
    public int getFoo() {return foo;}
    public int getBar() {return bar;}
}
public class Main {
    private MainData mainData;
    public Main(int foo, int bar) {
        this.mainData = new MainData(foo, bar);
    }
    public doSomeWork() {
        //correct behaviour
        this.mainData.getFoo() + this.mainData.getBar();
        //now I want to trick the pattern
        this.mainData = new MainData(this.mainData.getFoo(), this.mainData.getBar()+4);
        //I've changed bar :(
    }
}

自" readonly"属性不是编译强制的(与C#通过readonly保留字不同),在Java中,懒惰的开发人员可能会做这样的事情。如果这是真的,那我们为什么要使用这种设计模式呢?与其他模式(如单身人士)不同,这种模式不会强制执行任何操作,那么我们为什么要使用它呢?

  • 如果您能提供使用此模式的示例并且它具体帮助您解决某些软件问题,那将会很棒;
  • 让我们留在Java上:我知道在C#中一切都要容易得多,但由于readonly保留字,这种模式很简单;

感谢您的回复!

2 个答案:

答案 0 :(得分:6)

撰写Private Class Data的作者说,所谓的模式的意图是:

  

<强>意图

     
      
  • 控制对类属性的写入权限
  •   
  • 将数据与使用它的方法分开
  •   
  • 封装类数据初始化
  •   
  • 在构造函数
  • 之后提供新类型的final - final   

让我们一个一个地看看意图

  

控制对类属性的写访问权

我的观点是,控制对类属性的写访问只需通过方法和修饰符完成。 OOP调用此Encapsulation

  

将数据与使用它的方法分开

这对我来说没什么意义,因为面向对象的编程意味着将数据和方法结合在一起。这是一个对象是什么。将数据与使用它的方法分开似乎是一种贫血的方法。

  

封装类数据初始化

这就是我在构造函数中所做的。我没有看到将此代码移动到另一个类的好处。

  

在构造函数

之后提供新类型的final - final

此intent旨在最终引用数据类,但不要使数据类中的属性为final。我猜这就是为什么它被称为“新型决赛”。由于数据类仅保存数据并且方法与它们分离,因此如果数据类上没有setter,则无法修改数据。在这种情况下,数据是不可变的。因此,我没有看到数据类的好处只是使类的字段最终。

我的结论

我认为这种所谓的模式增加了复杂性而没有太大的好处。所以我不会用它。我称之为“所谓的模式”,因为

  

In software engineering, a software design pattern is a general reusable solution to a commonly occurring problem

我没有看到常见的问题。

答案 1 :(得分:0)

私人(或内部)班级的成员根本不是“只读”。 通过setter方法甚至可以直接更改它们的值没有问题。

拥有“只读”成员不是使用私有类的理由。这样做的一个原因是只能在包含(或外部)类的范围内访问该类。