设计模式(四)建造者模式
1、建造者模式也属于创建型模式,提供了一个创建对象的最佳方式。
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2、主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)。
3、例子:
- 工厂(建造者模式):负责制造汽车(组装过程和细节在工厂内)
- 汽车购买者(用户):你只需要说出你需要的型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车是怎么组装的,比如车轮、车门、发动机、方向盘等等)
4、类图
假设造房简化步骤:
(1)地基;
(2)钢筋工程;
(3)铺电线;
(4)粉刷。
如果建一个房子,首先要找一个建筑公司或者工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。
5、代码例子:
1 /** 2 * @author it-小林 3 * @desc 产品:房子 4 * @date 2021年07月13日 19:48 5 */ 6 public class Product { 7 8 private String build1; 9 private String build2; 10 private String build3; 11 private String build4; 12 13 public String getBuild1() { 14 return build1; 15 } 16 17 public void setBuild1(String build1) { 18 this.build1 = build1; 19 } 20 21 public String getBuild2() { 22 return build2; 23 } 24 25 public void setBuild2(String build2) { 26 this.build2 = build2; 27 } 28 29 public String getBuild3() { 30 return build3; 31 } 32 33 public void setBuild3(String build3) { 34 this.build3 = build3; 35 } 36 37 public String getBuild4() { 38 return build4; 39 } 40 41 public void setBuild4(String build4) { 42 this.build4 = build4; 43 } 44 45 @Override 46 public String toString() { 47 return "Product{" + 48 "build1='" + build1 + '\'' + 49 ", build2='" + build2 + '\'' + 50 ", build3='" + build3 + '\'' + 51 ", build4='" + build4 + '\'' + 52 '}'; 53 } 54 }
1 /** 2 * @author it-小林 3 * @desc 抽象的建造者 4 * @date 2021年07月13日 19:45 5 */ 6 public abstract class Builder { 7 8 /** 9 * 地基 10 */ 11 abstract void build1(); 12 13 /** 14 * 钢筋工程 15 */ 16 abstract void build2(); 17 18 /** 19 * 铺电线 20 */ 21 abstract void build3(); 22 23 /** 24 * 粉刷 25 */ 26 abstract void build4(); 27 28 abstract Product getProduct(); 29 }
1 /** 2 * @author it-小林 3 * @desc 具体建造者 4 * @date 2021年07月13日 19:50 5 */ 6 public class Worker extends Builder{ 7 private Product product; 8 9 public Worker(){ 10 product = new Product(); 11 } 12 13 @Override 14 void build1() { 15 product.setBuild1("地基"); 16 System.out.println("地基"); 17 } 18 19 @Override 20 void build2() { 21 product.setBuild2("钢筋工程"); 22 System.out.println("钢筋工程"); 23 } 24 25 @Override 26 void build3() { 27 product.setBuild3("铺电线"); 28 System.out.println("铺电线"); 29 } 30 31 @Override 32 void build4() { 33 product.setBuild4("粉刷"); 34 System.out.println("粉刷"); 35 } 36 37 @Override 38 Product getProduct() { 39 return product; 40 } 41 }
1 /** 2 * @author it-小林 3 * @desc 指挥:核心,负责指挥构建工程 4 * @date 2021年07月13日 20:08 5 */ 6 public class Director { 7 8 public Product build(Builder builder){ 9 builder.build2(); 10 builder.build1(); 11 12 builder.build3(); 13 builder.build4(); 14 return builder.getProduct(); 15 } 16 }
1 /** 2 * @author it-小林 3 * @desc 4 * @date 2021年07月13日 20:10 5 */ 6 public class Test { 7 public static void main(String[] args) { 8 //指挥 9 Director director = new Director(); 10 //指挥具体的工人完成产品 11 Product build = director.build(new Worker()); 12 System.out.println(build); 13 } 14 }
6、总结
上面示例是Builder模式的常规用法,指挥者类Director在Builder中具有很重要的作用,用于指导具体构建者如果构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director 和抽象建造者进行结合。
通过静态内部类方式实现零件无序装配构造,这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式,就可以生产出不同复杂产品。比如:麦当劳的套餐,服务员(具体建造者),可以随意搭配任意几种产品(零部件)组成一款套餐(产品),然后出售给客户。比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加简单灵活。
7、优缺点
a.优点:
- 产品的建造和表示分离,实现了解耦,使用建造者模式可以使客户端不必知道产品内部组成的细节;
- 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰;
- 具体的建造者类之间是相互独立的,这有利于系统的扩展,增加新的具体建造者无需修改原有类库的代码,符合”开闭原则“。
b.缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制;
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
8、应用场景
- 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品;
- 适合于一个具有较多的零件(属性)的产品(对象)的创建过程。
9、建造者与抽象工厂模式的比较
- 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族;
- 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象‘
- 如果将抽象工厂模式看成汽车配件生产过程,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。
如本文有侵权行为,请及时与本人联系,多多包涵!
小生初出茅庐,多多指教!
本文来自博客园,作者:it-小林,转载请注明原文链接:https://www.cnblogs.com/linruitao/p/14999693.html