1、概念算法
将一个复杂对像的构建与它的表示分离,使得一样的构建过程建立不一样的表示,又叫建造模式。ide
生成器模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法能够重用。采用不一样的构建实现,产生不一样的产品。因此生成器模式都会存在如下两个部分:ui
a.总体构建算法this
b.部件的构造和产品的装配spa
2、模式动机3d
生成器模式主要的功能就是构建复杂的产品,且是细化的、分步骤的构建产品,生成器模式重在一步一步解决构造复杂对像的问题。code
3、模式的结构blog
示意代码:接口
/** * * @ClassName: Product * @Description: TODO(被构建的产品对像接品) * @author beteman6988 * @date 2017年10月1日 上午11:26:33 * */ public interface Product { }
/** * 成生器接口,定义构建一个产品对像所须要的各个部件的操做 * @ClassName: Builder * @author beteman6988 * @date 2017年10月1日 上午11:28:12 * */ public interface Builder { /** * 构建某个部件 * @Title: buildPart * @param * @return void * @throws */ public void buildPart(); /** * 获取最终生成的产品对像 * @Title: getResult * @param @return * @return Product * @throws */ public Product getResult(); }
public class ConcreteBuilder implements Builder { //最终构建的产品 private Product resultProduct; /** * 获取最终生成的产品 * @Title: getResult * @param @return * @return Product * @throws */ @Override public Product getResult() { return this.resultProduct; } @Override public void buildPart() { // TODO Auto-generated method stub } }
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } /** * 指导生成器构建最终的产品对像 * @Title: construct * @param * @return void * @throws */ public void construct() { builder.buildPart(); builder.getResult(); } }
a.Builder:生成器接口,定义建立一个Product对像所须要的各个部件的操做。ip
b.ConcreteBuilder:具体生成器的实现,实现各个部件的建立,并负责组装Product对像的各个部件,同时还提供一个让用户获取组装完毕后的产品对像的方法。
c.Director:指导者,抽像出来的总体构建算法,主要用来使用Builder,以一个统一的过程来构建所须要的Product对像。
d.Product:产品,表示被生成器构建的复杂对像,包含多个部件。
4、模式样例
以一次台式机组装经历为例,当咱们去电脑城组装电脑时,首先导购小妹妹会拿出一张打印好的空白配置报价单,咱们在导购小妹的引导下,填写(固然小导购小妹填写)完了报价单后,而后组装工程师小哥就会跟据这个报价单,去仓库领取全部配件,而后就会将全部的配件组装在一块儿,一个完整的computer就组装好了,最后咱们交钱拿电脑走人。
运用生成器模式对上述过程进行分析:
a.Product:导购小妹给咱们的那个报价单能够说是一台最终computer product的一个抽像,当咱们填写完一个一个完整的报价单后,能够说一个具体的compueter已经有了,
不过目前仍是一堆零部件,要想获得一台完整的computer,还须要一个组装的过程。
b.Builder:咱们的组装工程师小哥,跟据不一样的具体报价单,都要去仓库忙一翻,要找到全部的部件,能够说只要有报价单,小哥都要将具体产口的每一个部件都要找出来,少一个能够说都不行,这个能够说是一个完整电脑每一个部件的抽像的建造(只是去仓库的相关位置拿到相关部件)。
c.ConcreteBuilder:组装工程师小哥跟据具体的报价单,去仓库找到相应的配件,并对每一个部件进行处理,该拆封的拆封,该插线的插线,而后依据必定的步骤组装将全部配件组装起来,组装成一台完整的电脑。
d.Director:电脑的组装能够说有固定的套路,能够说这个套路适应于全部的电脑组装,好比必须先有机箱,而后将主板装到机箱上,而后将cpu装到主板上,步骤不能乱。按这个套路,工程师小哥跟据不一样的报价单组装出不一样的computer.
代码以下:
public interface CBuilder { /** * 构建机箱 * @Title: buildBox * @param * @return void * @throws */ public void buildBox(); /** * 安装主板 * @Title: buildMBoard * @param * @return void * @throws */ public void buildMBoard(); /** * 安装CPU * @Title: buildCpu * @param * @return void * @throws */ public void buildCpu(); /** * 安装内存 * @Title: buildMemory * @param * @return void * @throws */ public void buildMemory(); /** * 安装硬盘 * @Title: buildHDisk * @param * @return void * @throws */ public void buildHDisk(); /** * 返回安装完毕的计算机 * @Title: getComputer * @param @return * @return ComputerA * @throws */ public ComputerA getComputer(); }
public class ComputerABuilder implements CBuilder {
private ComputerA aComputer=new ComputerA(); @Override public void buildBox() { this.aComputer.setBox("MAtx"); } @Override public void buildMBoard() { this.aComputer.setmBoard("AsusMb"); } @Override public void buildCpu() { this.aComputer.setCpu("Intel CoreI7"); } @Override public void buildMemory() { this.aComputer.setMemory("King stone DDR4"); } @Override public void buildHDisk() { this.aComputer.sethDisk("West Hard Disk 1T"); } @Override public ComputerA getComputer() { // TODO Auto-generated method stub System.out.println("Box:"+this.aComputer.getBox()); System.out.println("MBoard:"+this.aComputer.getmBoard()); System.out.println("Cpu:"+this.aComputer.getCpu()); System.out.println("Memory:"+this.aComputer.getMemory()); System.out.println("HDisk:"+this.aComputer.gethDisk()); return aComputer; } }
public class ComputerA { private String box; private String mBoard; private String cpu; private String memory; private String hDisk; public ComputerA() { super(); } public String getBox() { return box; } public void setBox(String box) { this.box = box; } public String getmBoard() { return mBoard; } public void setmBoard(String mBoard) { this.mBoard = mBoard; } public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } public String gethDisk() { return hDisk; } public void sethDisk(String hDisk) { this.hDisk = hDisk; } }
public class CDirector { private CBuilder theCBuilder; /** * @roseuid 59DB89BE02A1 */ public CDirector(CBuilder builder) { this.theCBuilder=builder; } /** * 独立出来的构建过程 */ public void construct() { this.theCBuilder.buildBox(); this.theCBuilder.buildMBoard(); this.theCBuilder.buildCpu(); this.theCBuilder.buildMemory(); this.theCBuilder.buildHDisk(); this.theCBuilder.getComputer(); } }
public class Client { public static void main(String[] args) { CBuilder builder=new ComputerABuilder(); CDirector director=new CDirector(builder); director.construct(); } }
运行结果以下:
Box:MAtx
MBoard:AsusMb
Cpu:Intel CoreI7
Memory:King stone DDR4
HDisk:West Hard Disk 1T
5、模式的约束
对于如下状况应当使用生成器模式:
1.须要生成的产品对像有复杂的内部结构。每一个内部成分能够是一个对像,也能够是产品的一个组成部分。
2.须要生产的产品的各个部件之间相互依赖,也就是一个部件的建造必须依赖另外一个部件建造完成才能建造,生成器模式能够强制实行一种分步骤的建造过程。
3.在对像的建立过程当中会使用到系统中的其它一些对像,这些对像在产品对像的建立过程当中不易获得。
6、模式的变体与扩展
1.省略抽像生成器Builder角色,若是系统肯定只会有一个具体生成器角色,那么就能够省略掉抽像生成器角色,类图以下:
2.省略指导者角色Director :若是抽像生成器Builder角色被省略,如上面的“1.”的状况,那么Director存在的意义就不大了,该角色也能够进行省略,以下图:
7、与其它模式的关系
1.生成器模式与工厂方法模式,这两个模式能够组合使用。生成器模式的Builder实现中,一般须要选择具体的部件实现。一个可行的方案就是实现为工厂方法,一般工厂方法来获取具体的部件对像,而后再进行部件的装配。
以下图:
2.生成器模式与抽像工厂模式,这两个模式是能够组合使用的,在生成器模式的Builder实现中,须要建立各个部件对像,而这些部件对像是有关联的,一般是构成的是一个复杂对像的部件对像。也就是说,Builder实现中,须要获取构成一个复杂对像的产品族,那天然就可使用抽像工厂模式来实现,这样一来抽像工厂负责了部件对像的建立,Builder实现里面则主要负责产品对像的总体构建了。
以下图:
其实建立模式和抽像工厂模式二者仍是有区别的,抽像工厂模式的主要目的是建立产品族,这个产品族里面的单个产品就至关因而构成一个复杂对像的部件对像,抽像工厂对像建立完成后就当即返回整个产品族;而生成器的模式的主要目的是按照构造算法,一步一步来构建一个复杂的产品对像,一般要等到整个构建过程结速后,才会获得最终的产品对像。
8、模式优缺点
生成器模式能够用同一个构建算法构建出表现上彻底不一样的产品,实现产品的构建和产品的表现上的分离。生成器模式正是把产品的构建过程独立出来,使它和具体产品的表现松散耦合,从而使得构建算法能够重用,而具体产品表现能够扩展和切换,从产品表现维度很好的支持开闭原则。