现实中有这样一种情况:有些对象的内部结构比较复杂,一般是由各种对象数据组合而来的.而且在某些
情况下,对象的属性必须按照一定的顺序赋值才有意义。这样无论是使用工厂模式、工厂方法模式亦或是抽
象工厂模式都不符合该情景。
解决上述问题,应该使用建造者模式。
建造者(Builder)模式:
建造者模式也叫生成器模式,他可以将一个产品对象的内部表象与产品的产生过程分离开来,从而
使一个建造过程生成具有不同内部表象的产品对象。简单的说建造产品的过程,就是“组合零件”的过
程,这些零件就相当于产品对象的内部表象,但是因为组合零件的过程十分复杂。因此,这个过程
往往被“外部化”到一个Builder对象去,Builder返回给用户一个全部零件构建完毕的产品对象。
说了这么多,接下来看看Builder模式的结构吧,了解其工作原理。
建造者(Builder)模式结构图:
建造者(Builder)模式角色:
建造者角色(Builder):是一个接口,用以规范产品对象的各个组成成分的建造,独立于应用程
序的商业逻辑。具体建造者必须实现接口。
具体建造者(Concrete Builder): 需要实现建造者角色接口,用于创建产品实例,并提供创建
的产品实例。
指导者角色(Director):调用ConcreteBuilder类创建对象,其本身并没有产品对象类的具体内容。
产品角色(Product):是该模式中要创建的复杂对象。
Director是用于和客户端打交道的角色,他将客户端创建产品的请求划分为对各个零件的创建请求,
再将这些请求交给Concrete Builder,Concrete Builder的创建过程对于客户端来说是隐藏的。
下面在以一个简单的例子程序说明、学习建造者模式!(关于台式机组装的问题)
一个台式机就相当于一个复杂对象,他拥有CPU,MONITOR,KEYBOARD等等组件,其创建过程
可以用创建者模式模拟。
首先构建一些Computer对象所需要的组件:
package com.kiritor; /**CPU*/ public class CPU { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public CPU() { // TODO Auto-generated constructor stub } public CPU(String name) { this.name=name; } } /**Keyboard*/ package com.kiritor; public class Keyboard { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Keyboard() { // TODO Auto-generated constructor stub } public Keyboard(String name) { this.name=name; } } /**Monitor*/ package com.kiritor; public class Monitor { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Monitor() { // TODO Auto-generated constructor stub } public Monitor(String name) { this.name=name; } }
Computer类:
package com.kiritor; /** * @author Kiritor 产品类 */ public class Computer { private CPU cpu; private Keyboard keyboard; private Monitor monitor; public CPU getCpu() { return cpu; } public void setCpu(CPU cpu) { this.cpu = cpu; } public Keyboard getKeyboard() { return keyboard; } public void setKeyboard(Keyboard keyboard) { this.keyboard = keyboard; } public Monitor getMonitor() { return monitor; } public void setMonitor(Monitor monitor) { this.monitor = monitor; } }
抽象建造者类:
package com.kiritor; /** * @author Kiritor * 抽象生成器*/ public abstract class Builder { abstract public void buildCPU(); abstract public void buildMonitor(); abstract public void buildKeyboard(); public Computer getComputer() { return null; } }
具体建造者类:
package com.kiritor; /** * @author Kiritor * 具体生成类*/ public class ConcreteBuilder extends Builder{ private Computer computer =new Computer(); @Override public void buildCPU() { // TODO Auto-generated method stub computer.setCpu(new CPU("i5")); } @Override public void buildKeyboard() { // TODO Auto-generated method stub computer.setKeyboard(new Keyboard("巧克力键盘")); } public void buildMonitor() { computer.setMonitor(new Monitor("三星")); } public Computer ConcreteBuilder() { // TODO Auto-generated constructor stub return computer; } }
指导类:
package com.kiritor; /** * @author Kiritor * 向导类*/ public class Director { /*指导复杂对象的创建过程,参数为建造类*/ public void buildComputer(Builder builder) { /*这里可以决定个对象的建造次序*/ builder.buildCPU(); builder.buildKeyboard(); builder.buildMonitor(); } }
测试类:
package com.kiritor; public class Client { public static void main(String[] args) { //首先实例化一个指导类 Director director = new Director(); //其次实例化一个具体建造类 Builder builder = new ConcreteBuilder(); director.buildComputer(builder);//客户端对复杂产品创建过程是不可见的 Computer computer = builder.getComputer(); } }
由以上代码可以看出,建造者模式中,客户端只是负责创建指导者和建造者对象,由
指导者
控制建造者创建产品,最后建造者把产品返回给客户端。因此产品的创建细节对于客户端来说
是隐藏的。
既然知道了建造者模式的工作方式,那么他的具体使用场景是什么呢?
1、需要生成的产品对象有复杂的结构
2、生成的产品的属性可以相互依赖,建造者模式可以强迫他们的顺序
建造者模式是产品的内部表象可以独立变化,建造者模式可以对客户端隐藏产品的组成细节
转载于:https://blog.51cto.com/kiritor/1226707