嵌入式开发环境构建
上周,我写了关于什么使图案成为反图案。 本周,我提出一种设计模式…或等待……也许这是一种反模式。 还是? 让我们看看!
当有一个类可以构建另一个实例时,构建器模式是一种编程风格。 构建器模式的最初目的是将对象的构建过程(在某些情况下可能非常复杂)与对象本身的类分开,因此构建器可以根据构建过程的进行方式交付不同类型的对象。 这是关注点分离的明确示例。
不可变的对象是创建的对象,在创建过程后不能更改。
建造者和不可变的对象自然而然地融合在一起。
构建器和构建的对象紧密相关,因此通常将它们放在同一程序包中。 但是为什么要在单独的类中实现它们? 一方面:它们当然必须是单独的类。 这就是全部。 但是另一方面:为什么构建器不能成为已构建类的内部类? Builder通常会以其自己的状态收集建筑物信息,并且在调用方请求构建对象时,此信息将用于构建已构建的对象。 大多数情况下,这种“使用”是复制操作。 如果生成器是内部类,则所有这些信息都可以存储在生成的对象中。 注意,内部类可以访问嵌入它的类的所有私有部分。 构建器可以创建尚未准备好的构建对象,并将构建信息存储在其中。 当要求建造所有东西时,便是最后的油画。
此模式后面是番石榴的不可变集合。 构建器是静态内部类。 如果查看ImmutableList的代码,您会发现抽象类内部有一个内部Builder
类。
但这不是嵌入构建器和实现的唯一方法。 如果将实现嵌入到生成器中怎么办? 构建器是唯一需要对类进行可变访问的代码。 定义该类实现的查询方法的接口对于其他任何人都应该足够。 如果我们到了这一点,为什么不创建Matrjoschka?
让我们有一个接口。 让我们在接口内部将一个生成器作为一个内部类(默认情况下为静态和公共,不能以任何其他方式)。 让我们将构建器内部的实现作为实现外部接口的私有静态类。
public interface Knight {boolean saysNi();public class Builder {private Implementation implementation = new Implementation();public Builder setState(String say) {implementation.say = say;return this;}public Implementation build() {Implementation knight = implementation;implementation = null;return knight;}private static class Implementation implements Knight {private String say;public boolean saysNi() {return say.indexOf("ni") != -1;}}}
}
构建器可以访问Knight实施的任何字段,因为它们在同一顶级类中。 (JLS1.7,第6.6.1节,确定可访问性)
除了使用生成器之外,没有其他方法(讨厌的反射技巧或字节码滥用(目前已超出范围))可以访问实现。
该构建器可用于构建实现,一旦返回该实现,就无法再访问它,无法通过该构建器修改该实现。 如果实现是不可变的,则可以保证保存状态。
这是图案还是反图案?
翻译自: https://www.javacodegeeks.com/2014/02/design-pattern-immutable-embedded-builder.html
嵌入式开发环境构建