在不破坏不变性的情况下更新不可变对象

Update immutable object without breaking immutability

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

我怎样才能达到类似的效果 Customer.Builder.from(anotherCustomer).replaceOrder(oldOrder,newOrder).with(newName).build()

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

我正在使用 Java。

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

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

    String uppercase = "hello".toUpperCase()

我让流利的打字变得简单易用

    String uppercasewithoutletterL = "hello".toUpperCase().replace("L","")

您可以在对象类型中实现 Cloneable 接口。 另一种选择是为您的不可变对象提供构建器,它可以从现有对象创建新实例。像 those 伙计们完成了...

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);
        }
    }
}

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

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');