繁体   English   中英

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

[英]Update immutable object without breaking immutability

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

如何实现像Customer.Builder.from(anotherCustomer).replaceOrder(oldOrder,newOrder).with(newName).build()之类的东西。

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

我正在使用Java。

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

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

我知道更新不可变对象的最好方法是返回对象的修改副本,就像java String一样

    String uppercase = "hello".toUpperCase()

我很容易使用流利的打字

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM