表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
相关模式:思路和模板方法模式很像,模板方法是封装算法流程,对某些细节,提供接口由子类修改,建造者模式更为高层一点,将所有细节都交由子类实现。
建造者模式的使用情况:
以下情况应当使用建造者模式:
1、需要生成的产品对象有复杂的内部结构。
2、需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
3、 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
优缺点:
优点:1、建造者模式的使用使得产品内部表象可以独立的变化,使客户端不必知道产品内部组成细节。
2、每一个Builder都相对独立,而与其它的Builder无关。
3、可以使对构造过程更加精细控制,以降低控制细节的风险。
4、将构建代码和表示代码分开。
缺点:1、由于其的变化点在于对象创建的细节,故其也难于分步骤构建的算法需求的变动,因为其关注的是对象创建顺序。
建造者模式一般适用于稳定的系统,比如说同样是对人的描述,如果描述的是正常人,就可用,但是对于残疾人,因为系统不再稳定,再使用的话就无法满足“开闭原则”了。
当要生产的一种产品具有相同的结构,并且每个构件的生产都很繁杂,就可以用Builder模式将具体构件的生产与整个成品的组装分离开来。还是拿本文的代码来举例,生产一台笔记本,笔记本的厂家不需要知道CPU怎么生产的,不需要关心内存怎么生产的,也不需要关心主板怎么生产的等。当他在生产一台笔记本的时候,只会说,我要一块Intel的CPU,于是就有了CPU(至于Intel的CPU怎么生产的他不关心,他只要一个CPu),他又说我要一块金士顿内存,于是就有了金士顿内存,这样直到他得到了所有的构件,然后他把这些构件组装起来,组成一台笔记本卖给客户。这就是一个典型的Builder模式。下面是代码:
/**
* CPU抽象类
*/
public abstract class CPU {
public abstract CPU getCPU();
}
/**
* Intel的cpu
*/
public class IntelCPU extends CPU {
public IntelCPU(){};
@Override
public CPU getCPU() {
// TODO Auto-generated method stub
return new IntelCPU();
}
public String toString(){
return " IntelCPU ";
}
}
/**
* AMD的cpu
*/
public class AMDCPU extends CPU {
public AMDCPU(){};
@Override
public CPU getCPU() {
// TODO Auto-generated method stub
return new AMDCPU();
}
public String toString(){
return " AMDCPU ";
}
}
/**
* 内存抽象类
*/
public abstract class Memory {
public abstract Memory getMemory();
}
/**
* 金士顿内存
*/
public class KingstonMemory extends Memory {
public KingstonMemory(){};
@Override
public Memory getMemory() {
return new KingstonMemory();
}
public String toString(){
return " KingstonMemory ";
}
}
/**
* 宇瞻内存
*/
public class ApacerMemory extends Memory {
public ApacerMemory(){};
@Override
public Memory getMemory() {
// TODO Auto-generated method stub
return new ApacerMemory();
}
public String toString(){
return " ApacerMemory ";
}
}
**
* 主板抽象类
*/
public abstract class Mainboard {
public abstract Mainboard getMainboard();
}
/**
* 华硕主板
*/
public class AsusMainboard extends Mainboard {
public AsusMainboard(){};
@Override
public Mainboard getMainboard() {
// TODO Auto-generated method stub
return new AsusMainboard();
}
public String toString(){
return " AsusMainboard ";
}
}
/**
* 技嘉主板
*/
public class GaMainboard extends Mainboard {
public GaMainboard(){}
@Override
public Mainboard getMainboard() {
return new GaMainboard();
};
public String toString(){
return " GaMainboard ";
}
}
/**
* 计算机所需组件
*/
public class Computer {
private CPU cpu;
private Memory memory;
private Mainboard mainboard;
public CPU getCpu() {
return cpu;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public Memory getMemory() {
return memory;
}
public void setMemory(Memory memory) {
this.memory = memory;
}
public Mainboard getMainboard() {
return mainboard;
}
public void setMainboard(Mainboard mainboard) {
this.mainboard = mainboard;
}
}
/**
* 计算机Builder
*/
public interface ComputerBuilder {
public void buildCPU();
public void buildMemory();
public void buildMainboard();
public Computer getComputer();
}
/**
* 联想计算机Builder
*/
public class LenoveComputerBuilder implements ComputerBuilder {
private Computer lenoveComputer=null;
public LenoveComputerBuilder(){
lenoveComputer=new Computer();
}
@Override
public void buildCPU() {
lenoveComputer.setCpu(new IntelCPU());
}
@Override
public void buildMemory() {
lenoveComputer.setMemory(new KingstonMemory());
}
@Override
public void buildMainboard() {
lenoveComputer.setMainboard(new AsusMainboard());
}
@Override
public Computer getComputer() {
buildCPU();
buildMemory();
buildMainboard();
return lenoveComputer;
}
}
/**
* 惠普计算机Builder
*/
public class HPComputerBuilder implements ComputerBuilder {
private Computer HPComputer=null;
public HPComputerBuilder(){
HPComputer = new Computer();
}
@Override
public void buildCPU() {
HPComputer.setCpu(new AMDCPU());
}
@Override
public void buildMemory() {
HPComputer.setMemory(new ApacerMemory());
}
@Override
public void buildMainboard() {
HPComputer.setMainboard(new GaMainboard());
}
@Override
public Computer getComputer() {
buildCPU();
buildMemory();
buildMainboard();
return HPComputer;
}
}
public class Director {
private ComputerBuilder builder;
public Director(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
return builder.getComputer();
}
}
public class TestBuilder {
/**
* @param args
*/
public static void main(String[] args) {
Computer lenoveComputer,hpComputer;
ComputerBuilder lenoveComputerBuilder = new LenoveComputerBuilder();
ComputerBuilder hpComputerBuilder = new HPComputerBuilder();
Director director;
director = new Director(lenoveComputerBuilder);
lenoveComputer=director.construct();
director = new Director(hpComputerBuilder);
hpComputer=director.construct();
System.out.println("lenoveComputer is made by:"+lenoveComputer.getCpu()+lenoveComputer.getMemory()+lenoveComputer.getMainboard());
System.out.println("hpComputer is made by:"+hpComputer.getCpu()+hpComputer.getMemory()+hpComputer.getMainboard());
}
}
运行结果:
lenoveComputer is made by: IntelCPU KingstonMemory AsusMainboard
hpComputer is made by: AMDCPU ApacerMemory GaMainboard
注解:
在main函数里面,director调用了builder里面的getComputer()方法,getComputer()方法实际就是组装的过程,getComputer()里面的buildCPU(); buildMemory(); buildMainboard(); 就是在购买构件,而这些构件生产的具体过程放在了这些构件自身的类里面,可以看到buildCPU()里面有new一个对象,这就是在进行生产。这样就达到了组装和生产构件之间的分离。
最后,说说Builder模式和Factory模式之间区别的理解。Builder和Factory之间的区别就是组装和生产之间的区别,Builder着重将组装和构件的生产分离,Factory着重于优化生产的过程。本文的代码实际上还可以进行重构,例如,在buildCPU()函数里面,用到了new这个关键字,实际上可以将这个new换成工厂类,让工厂类来生产CPU。换一种说法,就是Factory不进行组装,Builder进行组装,当Factory进行组装的时候,它就变成Builder了。
下期预告,Prototype模式!