建造者模式和工厂模式都是常见的创建型设计模式,他们都通过封装了对象的创建过程使得客户端与具体对象的创建解耦,从而简化了客户端代码,提高了代码的可维护性和可理解性。那么,两者的区别又是什么呢?先上UML图
工厂模式
建造者模式
根据UML可以看得出来,工厂模式通过工厂类直接返回可用的对象,而建造者却需要通过指挥者Director来组装对象的各个部分并返回可用的对象,这就是两者的主要区别所在:工厂模式强调返回可用对象,建造者模式强调可用对象的构建步骤。因此建造者模式创建的对象通常都比较复杂且多变。对于复杂的理解,比如对象的某些属性需要访问数据库获取,另一些属性则需要远程调用其它服务来获取。对于多变的理解,可以参考下面的链式调用
public class Person {
private String name;
private Integer age;
private Double height;
// 具体建造者
public static class Builder {
private Person person;
public Builder() {
person = new Person();
}
public Builder buildName(String name) {
person.name = name;
return this;
}
public Builder buildAge(Integer age) {
person.age = age;
return this;
}
public Builder buildHeight(Double height) {
person.height = height;
return this;
}
public Person build() {
return person;
}
}
public static void main(String[] args) {
Builder builder = new Builder();
// 链式调用构建对象
builder.buildName("John")
.buildAge(18)
.buildHeight(1.88)
.build();
}
}
这是一个典型的链式调用,这里省略显式的指挥者角色,由客户端直接充当指挥者,客户端可以通过Builder灵活地传递对象参数来构造需要的对象。如果对象的创建步骤相对固定,则可以创建PersonDirector来构造具体的Person对象。
建造者模式可以看作是更低层级的具体实现,它通过一步一步地组合各个部件(属性或组件)来创建一个对象,客户端可以通过定制不同的建造者来制定对象的各个部分以及构造的顺序。尤其适合于创建对象的内部结构复杂、组成部分及其装配顺序可变的情况,但与工厂模式不同,它更关注对象的构建过程。
工厂模式可以看作是更高层级的创建对象,主要是为了隐藏创建对象的复杂过程,让客户端不需要了解对象的具体实现类,它提供的是某种“标准”或“预制”的对象创建服务,但与建造者模式不同,它更关注的是对象的类型。
对于具体应该使用哪种创建型模式,通常,设计从工厂方法开始,并随着设计发现需要更多灵活性的地方而向抽象的工厂、原型或构建器(更灵活、更复杂)发展。
最后,设计模式都有很多变体,比如建造者模式的链式调用可以让客户端充当指挥者,工厂模式又分为简单工厂、工厂方法以及抽象工厂等。使用时要根据需要灵活运用(甚至可以组合各种设计模式及比如在工厂中融入建造者等),切不可为了使用设计模式而生搬硬套。
下面的链接讲解各种设计模式以及使用场景,值得收藏
Design Patterns (refactoring.guru)
设计模式总结文章(一边学习一边更新中)
建造者模式和工厂模式的区别-CSDN博客