基础:
概念:建造者模式是为了创建一个复杂对象用的,多复杂呢,有很多零件,很多步骤,并且可能还需要兼容不同步骤,不同原料。它把构建单个独立的原件builder和装饰director过程相分离。那么不同原件和不同装配者都可以建造出不同的产品来。
举个例子,比如KFC的汉堡,全国各地的味道都一样,那是因为配方原件是一样的,并且原料相加也是一样的,所以最终产品是一样的。那个配方,有面包,有芝士,有炸鸡腿,这些原料的构建我们可以通过构建者的方法去生成(但是具体可以是工厂模式生产的,我们只要从生产的好的拿来用就行了),然后封装成builder对象(比如build面包,build炸鸡腿)。那么有了原料之后,就需要装配,我们拿到打包好的原料(就是budiler对象),然后通过director对象装配,这个装配对象就定义了我们拿到builder之后怎么装配,先加面包,然后放蔬菜,然后放鸡腿,这样最后返回一个成品就行了,这就是建造者模式。
那么目录结构是这样的:
我们需要造一个电脑,有cpu、内存和闪存sata,这几个是需要组合的构建原料,所以Computer.java封装了这几个属性。
package BuilderBlog;
import BuilderBlog.Bean.Cpu;
import BuilderBlog.Bean.Memory;
import BuilderBlog.Bean.Sata;
import BuilderBlog.ComputerImp.AComputerBuilder;
import BuilderBlog.ComputerImp.BComupterBuilder;
import BuilderBlog.ComputerImp.ComputerDirector;
import BuilderBlog.ComputerInf.CBuilder;
import BuilderBlog.ComputerInf.CDirector;
public class Computer {
Cpu cpu;
Memory memory;
Sata sata;
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 Sata getSata() {
return sata;
}
public void setSata(Sata sata) {
this.sata = sata;
}
@Override
public String toString() {
return "Computer [cpu=" + cpu + ", memory=" + memory + ", sata=" + sata + "]";
}
public static void main(String[] args){
CBuilder builder = new AComputerBuilder();
CBuilder builder02 = new BComupterBuilder();
Computer computer00 = new ComputerDirector(builder).makeIt();
Computer computer01 = new ComputerDirector(builder02).makeIt();
System.out.println(computer00.toString());
System.out.println(computer01.toString());
}
}
然后声明两个接口,CBuilder和CDirector用来定义方法,之后是两种实现类,分别实现CBuilder接口和CDirector接口:
package BuilderBlog.ComputerImp;
import BuilderBlog.Bean.Cpu;
import BuilderBlog.Bean.Memory;
import BuilderBlog.Bean.Sata;
import BuilderBlog.ComputerInf.CBuilder;
/**
* 低配电脑
* @author cloudhuan
*
*/
public class AComputerBuilder implements CBuilder{
@Override
public Cpu buildCpu() {
// TODO Auto-generated method stub
return new Cpu();
}
@Override
public Memory buildMemory() {
// TODO Auto-generated method stub
return new Memory();
}
@Override
public Sata buildSata() {
// TODO Auto-generated method stub
return null;
}
}
和
package BuilderBlog.ComputerImp;
import BuilderBlog.Computer;
import BuilderBlog.ComputerInf.CBuilder;
import BuilderBlog.ComputerInf.CDirector;
public class ComputerDirector implements CDirector{
CBuilder builder;
public ComputerDirector(CBuilder builder){
this.builder = builder;
}
@Override
public Computer makeIt() {
// TODO Auto-generated method stub
Computer computer = new Computer();
computer.setCpu(builder.buildCpu());
computer.setMemory(builder.buildMemory());
computer.setSata(builder.buildSata());
return computer;
}
}
上面两个实现类就是具体怎么取到原料处理,以及拿到这些原料做些什么操作,也就是构建者和装配者的具体实现类。
最后使用可以分别创建一个builder和director,并调用director的makeIt方法创建一个对象出来。
public static void main(String[] args){
CBuilder builder = new AComputerBuilder();
Computer computer00 = new ComputerDirector(builder).makeIt();
System.out.println(computer00.toString());
}
那么问题来了,怎么扩展呢?
我们知道,建造者是为了把创建和装配过程分离,实现耦合的,所以你可以定义自己的builder实现类,比如源码的BComupterBuilder.java就是自己新建的创建者,可以实现装配另一种功能的对象。
扩展:
在学习了java的创建者后,突然想到android也有部分api用了builder模式,比如notification和dialog,那么它们是怎样实现的呢,在我理解是把装配者封装了,但是创建的这一过程留给用户,上面那个例子是装造这一过程也封装了,两者因地置宜吧。
那么调用是这样的:
public static void main(String[] args){
Computer computer = new ComputerBuilder().
buildCpu(new Cpu()).
buildMemory(new Memory()).
makeIt();
}
实现是这样的:
package BuilderBlog;
import BuilderBlog.Bean.Cpu;
import BuilderBlog.Bean.Memory;
import BuilderBlog.Bean.Sata;
import BuilderBlog.ComputerInf.CBuilder;
import BuilderBlog.ComputerInf.CDirector;
public class ComputerBuilder implements CDirector{
private Computer computer;
public ComputerBuilder buildCpu(Cpu cpu) {
computer.setCpu(cpu);
return this;
}
public ComputerBuilder buildMemory(Memory memory) {
computer.setMemory(memory);
return this;
}
public ComputerBuilder buildSata(Sata stat) {
computer.setSata(stat);
return this;
}
@Override
public Computer makeIt() {
// TODO Auto-generated method stub
return computer;
}
public static void main(String[] args){
Computer computer = new ComputerBuilder().
buildCpu(new Cpu()).
buildMemory(new Memory()).
makeIt();
}
}
最后,源码: