概述
- 使用多个简单对象一步步构建成一个复杂对象
- 有时面临“一个复杂对象”的的创建工作,通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂的对象各个部分经常面临着剧烈的变化,但将他们组合在一起的算法却相对稳定
- 将一个复杂对象的构建(HouseBuilder)与其表示(House)相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)
- 使用相同的创建代码生成不同形式的对象
- 用于“分步骤构建一个复杂对象”,分步骤是个稳定算法,而复杂对象的各个部分经常变化
- 变化点在哪里,封装哪里。主要应对“复杂对象各个部分”的频繁需求变动,缺点在于难以应对“分步骤构建算法”的需求变动
- construct不稳定--虚函数,子类--参数和返回值变化--基类,子类
- 注意不同语言中构造器内调用虚函数的差别(C++,C#)
场景
- 肯德基的汉堡、薯条、可乐、炸鸡等是不变的,而套餐组合是经常变化的
示例
builder.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class House{ 2 //.... 3 }; 4 5 class HouseBuilder { 6 public: 7 House* GetResult(){ 8 return pHouse; 9 } 10 virtual ~HouseBuilder(){} 11 protected: 12 13 House* pHouse; 14 virtual void BuildPart1()=0; 15 virtual void BuildPart2()=0; 16 virtual void BuildPart3()=0; 17 virtual void BuildPart4()=0; 18 virtual void BuildPart5()=0; 19 20 }; 21 22 class StoneHouse: public House{ 23 24 }; 25 26 class StoneHouseBuilder: public HouseBuilder{ 27 protected: 28 29 virtual void BuildPart1(){ 30 //pHouse->Part1 = ...; 31 } 32 virtual void BuildPart2(){ 33 34 } 35 virtual void BuildPart3(){ 36 37 } 38 virtual void BuildPart4(){ 39 40 } 41 virtual void BuildPart5(){ 42 43 } 44 45 }; 46 47 48 class HouseDirector{ 49 50 public: 51 HouseBuilder* pHouseBuilder; 52 53 HouseDirector(HouseBuilder* pHouseBuilder){ 54 this->pHouseBuilder=pHouseBuilder; 55 } 56 57 House* Construct(){ 58 59 pHouseBuilder->BuildPart1(); 60 61 for (int i = 0; i < 4; i++){ 62 pHouseBuilder->BuildPart2(); 63 } 64 65 bool flag=pHouseBuilder->BuildPart3(); 66 67 if(flag){ 68 pHouseBuilder->BuildPart4(); 69 } 70 71 pHouseBuilder->BuildPart5(); 72 73 return pHouseBuilder->GetResult(); 74 } 75 };
示例2
ParlourDecorator.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package Builder; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 public class ParlourDecorator 7 { 8 public static void main(String[] args) 9 { 10 try 11 { 12 Decorator d; 13 d=(Decorator) ReadXML.getObject(); 14 ProjectManager m=new ProjectManager(d); 15 Parlour p=m.decorate(); 16 p.show(); 17 } 18 catch(Exception e) 19 { 20 System.out.println(e.getMessage()); 21 } 22 } 23 } 24 25 class Parlour 26 { 27 private String wall; 28 private String TV; 29 private String sofa; 30 31 public void setWall(String wall) 32 { 33 this.wall=wall; 34 } 35 public void setTV(String TV) 36 { 37 this.TV=TV; 38 } 39 public void setSofa(String sofa) 40 { 41 this.sofa=sofa; 42 } 43 public void show() 44 { 45 JFrame jf=new JFrame("建造者模式"); 46 Container contentPane=jf.getContentPane(); 47 JPanel p=new JPanel(); 48 JScrollPane sp=new JScrollPane(p); 49 String parlour=wall+TV+sofa; 50 System.out.println(parlour); 51 JLabel l=new JLabel(new ImageIcon("src/Builder/"+parlour+".jpg")); 52 p.setLayout(new GridLayout(1,1)); 53 p.setBorder(BorderFactory.createTitledBorder("客厅")); 54 p.add(l); 55 contentPane.add(sp,BorderLayout.CENTER); 56 jf.pack(); 57 jf.setVisible(true); 58 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 59 } 60 } 61 62 abstract class Decorator 63 { 64 protected Parlour product=new Parlour(); 65 public abstract void buildWall(); 66 public abstract void buildTV(); 67 public abstract void buildSofa(); 68 69 public Parlour getResult() 70 { 71 return product; 72 } 73 } 74 75 class ConcreteDecorator1 extends Decorator 76 { 77 public void buildWall() 78 { 79 product.setWall("w1"); 80 } 81 public void buildTV() 82 { 83 product.setTV("TV1"); 84 } 85 public void buildSofa() 86 { 87 product.setSofa("sf1"); 88 } 89 } 90 91 class ConcreteDecorator2 extends Decorator 92 { 93 public void buildWall() 94 { 95 product.setWall("w2"); 96 } 97 public void buildTV() 98 { 99 product.setTV("TV2"); 100 } 101 public void buildSofa() 102 { 103 product.setSofa("sf2"); 104 } 105 } 106 107 class ProjectManager 108 { 109 private Decorator builder; 110 public ProjectManager(Decorator builder) 111 { 112 this.builder=builder; 113 } 114 public Parlour decorate() 115 { 116 builder.buildWall(); 117 builder.buildTV(); 118 builder.buildSofa(); 119 return builder.getResult(); 120 } 121 }
ReadXML.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package Builder; 2 3 import javax.xml.parsers.*; 4 import org.w3c.dom.*; 5 import java.io.*; 6 class ReadXML 7 { 8 public static Object getObject() 9 { 10 try 11 { 12 DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance(); 13 DocumentBuilder builder=dFactory.newDocumentBuilder(); 14 Document doc; 15 doc=builder.parse(new File("src/Builder/config.xml")); 16 NodeList nl=doc.getElementsByTagName("className"); 17 Node classNode=nl.item(0).getFirstChild(); 18 String cName="Builder."+classNode.getNodeValue(); 19 System.out.println("新类名:"+cName); 20 Class<?> c=Class.forName(cName); 21 Object obj=c.newInstance(); 22 return obj; 23 } 24 catch(Exception e) 25 { 26 e.printStackTrace(); 27 return null; 28 } 29 } 30 }
config.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <config> 3 <className>ConcreteDecorator1</className> 4 </config>
新类名:Builder.ConcreteDecorator1
w1TV1sf1