java - 是否有任何模式可用于实现 holder 对象的可变和不可变版本?

标签 java design-patterns immutability

在我的应用程序中,我有几种holder 对象,其主要目的是存储异构相关数据。它们的生命周期可以分为两部分:

  1. 一旦可用就收集数据;
  2. 在持有人的余生中提供对存储数据的只读访问权限。

使持有者不可变是非常诱人的,但数据不能一次性传递给构造函数。我看到的最简单的解决方法是制作两个版本的 holder 类,一个是可变的,另一个不是:

public class MutableHolder {
    public int field1;
    public String field2;
    // ...
    public Object fieldN;
}

public class Holder {
    public final int field1;
    public final String field2;
    // ...
    public final Object fieldN;

    public Holder(MutableHolder mutableHolder) {
        this.field1 = mutableHolder.field1;
        this.field2 = mutableHolder.field2;
        // ...
        this.fieldN = mutableHolder.fieldN;
    }
}

但是,我觉得这种方法违反了 DRY 原则(如果我想更改任何内容,我不能忘记更新两个类的字段以及构造函数)并且容易出错。所以这是我的问题:是否有任何我不知道的现有模式来实现 holder 对象的可变和不可变版本?

编辑

我突然发现上面的代码是构建器模式的一个非常简单的版本(参见 thisthis )。这让我认为在这种情况下,DRY 违规被认为是可以接受的。

最佳答案

我也被这个绊倒了一段时间。这是我想出的一种设计模式,我在其他地方没有见过。

public class Bob
{
    // member variables
    private int value;

    // simple constructor
    private Bob()
    {
        value(0);
    }

    // constructor with value
    private Bob(int value)
    {
        value(value);
    }

    // get value
    public final int value()
    {
        return this.value;
    }

    // set value
    private final void value(int value)
    {
        this.value = value;
    }


    // mutable class modifies base class
    public static class Mutable extends Bob
    {
        // simple constructor
        private Mutable()
        {
            super();
        }

        // constructor with value
        private Mutable(int value)
        {
            super(value);
        }

        // set value
        public final void value(int value)
        {
            super.value(value);
        }
    }


    // factory creator for immutable
    public static final Bob immutable(int value)
    {
        return new Bob(value);
    }

    // factory creator for mutable
    public static final Mutable mutable()
    {
        return new Mutable();
    }

    // another mutable factory creator
    public static final Mutable mutable(int value)
    {
        return new Mutable(value);
    }
}
  • 该类不是最终类,子类化应该是安全的。
  • 所有的构造函数都必须是私有(private)的。
  • 公共(public)访问器应该是最终的。
  • 基类中的私有(private)修改器应该是最终的。
  • Mutable 类中的公共(public)修改器应该是最终的。
  • 使用工厂方法构造不可变和可变对象。

这类似于子类可变模式,但由于 Mutable 类是一个内部类,它可以访问基类中的私有(private)字段和方法,因此不需要保护任何可能被覆盖的内容。基类就像一个标准的可变类,除了构造函数和修改器是私有(private)的。可变子类是一个薄层(每个方法都是 super ...),它暴露了修改器。

创建一个不可变实例:Bob test1 = Bob.immutable(99);创建一个可变实例: Bob.Mutable test2 = Bob.mutable();

关于java - 是否有任何模式可用于实现 holder 对象的可变和不可变版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26662868/

相关文章:

java - JAXB 将子类的实例解码到列表中

c# - 这个图案叫什么?软锁?

java - 无法推断功能接口(interface)类型 Java 8

java - 将 jpeg 图像转换为透明 png 图像

java - Android,在启动时为 EditText 设置文本

mysql - 库存管理数据库: definition vs.实例

c# - .NET Framework 中是否使用了责任链?

自动映射器和不变性

如果我们只允许局部变量是可变的,我们可以防止共享可变状态吗?

javascript - 如何在动态对象内的数组中添加/删除