4

如何在不破坏不变性的情况下从另一个不可变对象获取更新的不可变对象。类似于在 Scala 中实现事物的方式或在 Immutables 库中实现事物的方式。

我怎样才能实现类似 Customer.Builder.from(anotherCustomer).replaceOrder(oldOrder,newOrder).with(newName).build()

重用旧对象并将我想要的所有更改排队以构建新对象。

我正在使用 Java。

4

4 回答 4

5
public class Customer {
    private String name;    
    private Order order

    private Customer(CustomerBuilder builder) {
        this.name = builder.name;
        this.order = builder.order;
    }

    public Customer replace(Order order) {
        return new CustomerBuilder().name(this.name).order(order).build();
    }

    public static class CustomerBuilder {
        private String name;    
        private Order order

        public CustomerBuilder name(String name) {
            this.name = name;
            return this;
        }

        public CustomerBuilder order(Order order) {
            this.order = order;
            return this;
        }

        public Customer build() {
            return new Customer(this);
        }
    }
}
于 2016-04-05T08:33:47.083 回答
1

我推荐这本书涵盖该主题: https ://www.amazon.ca/Effective-Java-Edition-Joshua-Bloch/dp/0321356683

我知道更新不可变对象的最佳方法是返回对象的修改副本,例如 java String

    String uppercase = "hello".toUpperCase()

我使易于使用的流利打字

    String uppercasewithoutletterL = "hello".toUpperCase().replace("L","")
于 2016-04-04T20:06:42.350 回答
1

这是一个小递归函数,它创建了一个更改后的不可变对象。它重新创建包含更改的每个嵌套对象。

const changeImmutable = (immutable: any, path: string[], newVal: any): any => {
  if(path.length) {
    let copy = Array.isArray(immutable) ? [...immutable] : {...immutable};
    copy[path[0]] = changeImmutable(copy[path[0]], path.slice(1), newVal);
    return copy;
  }
  return newVal; 
};

使用示例

let immutableObj = {a: {b: [{c: 'foo'}]}};

// change 'foo' to 'bar'
let newImmutableObj = changeImmutable(immutableObj, ['a', 'b', 0, 'c'], 'bar');
于 2018-10-27T18:38:17.063 回答
0

您可以在对象类型中实现Cloneable接口。另一种选择是为您的不可变对象提供构建器,该构建器可以从现有对象创建新实例。就像那些家伙所做的那样...

于 2016-04-04T20:07:39.973 回答