建造者模式(Builder),将一个复杂对象的构建和表示分离,使得同样的构建过程可以创建不同的表示。
如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。
示例:使用建造者模式画小人
小人有高矮胖瘦,但是每一个小人都有一个头,两个手,两个腿,可以把这些必须要建造的过程和细节定义一个建造者类,规定必须要有的建造过程。
抽象的建造者类
abstract class PersonBuilder {protected Graphics g;public PersonBuilder(Graphics g){this.g = g;}public abstract void buildHead(); //头public abstract void buildBody(); //身体public abstract void buildArmLeft(); //左手public abstract void buildArmRight(); //右手public abstract void buildLegLeft(); //左脚public abstract void buildLegRight(); //右脚
}
具体建造者— 瘦小人
class PersonThinBuilder extends PersonBuilder {public PersonThinBuilder(Graphics g){super(g);}// 实现具体的建造方法,自定义建造细节public void buildHead(){g.drawOval(150, 120, 30, 30); //头}public void buildBody(){g.drawRect(160, 150, 10, 50); //身体}public void buildArmLeft(){g.drawLine(160, 150, 140, 200); //左手}public void buildArmRight(){g.drawLine(170, 150, 190, 200); //右手}public void buildLegLeft(){g.drawLine(160, 200, 145, 250); //左脚}public void buildLegRight(){g.drawLine(170, 200, 185, 250); //右脚 }
}
具体的建造者—胖小人
class PersonFatBuilder extends PersonBuilder {public PersonFatBuilder(Graphics g){super(g);}// 实现具体的建造方法,自定义建造细节public void buildHead(){g.drawOval(250, 120, 30, 30); //头}public void buildBody(){g.drawOval(245, 150, 40, 50); //身体}public void buildArmLeft(){g.drawLine(250, 150, 230, 200); //左手}public void buildArmRight(){g.drawLine(280, 150, 300, 200); //右手}public void buildLegLeft(){g.drawLine(260, 200, 245, 250); //左脚}public void buildLegRight(){g.drawLine(270, 200, 285, 250); //右脚}
}
抽象的建造者规定了必须要有的建造过程,具体的建造者,实现必须的建造过程,根据需求自定义建造细节。
在建造者和使用者之间还需要一个指挥者,来控制具体建造过程,同时隔离用户与建造过程的关联。
指挥者
class PersonDirector {private PersonBuilder pb;// 初始化时指定需要建造什么样的小人public PersonDirector(PersonBuilder pb){this.pb = pb;} // 根据用户的需要建造小人public void CreatePerson(){pb.buildHead(); // 头pb.buildBody(); // 身体pb.buildArmLeft(); // 左手pb.buildArmRight(); // 右手pb.buildLegLeft(); // 左脚pb.buildLegRight(); // 右脚}
}
客户端
class Test extends JFrame {public Test() {setSize(400, 400);setDefaultCloseOperation(EXIT_ON_CLOSE);setLocationRelativeTo(null);}public void paint(Graphics g) {PersonBuilder gThin = new PersonThinBuilder(g);// 使用指挥者,控制建造过程PersonDirector pdThin = new PersonDirector(gThin);pdThin.CreatePerson();PersonBuilder gFat = new PersonFatBuilder(g);PersonDirector pdFat = new PersonDirector(gFat);pdFat.CreatePerson();}public static void main(String[] args) {new Test().setVisible(true);}
}
Builder类,是为创建Product对象的各个部分指定的抽象接口(抽象的小人)。
ConcreteBuilder类,具体的建造者,实现 Builder接口,构造和装配各个部件(具体的小人)。
Product,建造出来的具体对象(小人对象)。
Director ,指挥者,使用 Builder接口的对象,
何时需要使用建造者模式?
建造者模式主要用于创建一些复杂的对象,这些对象内部子对象的建造顺序通常是稳定的,但每个子对象本身的构建通常面临复杂的变化。
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
产品类
class Product{ArrayList parts = new ArrayList();//添加新的产品部件public void add(String part){parts.add(part);}//列举所有产品部件public void show(){for(String part : parts){System.out.println(part);}}
}
抽象的建造者类
abstract class Builder {public abstract void buildPartA(); //建造部件Apublic abstract void buildPartB(); //建造部件Bpublic abstract Product getResult(); //得到产品
}
具体的建造者类
// 具体建造者1
class ConcreteBuilder1 extends Builder {private Product product = new Product();public void buildPartA(){product.add("部件A");}public void buildPartB(){product.add("部件B");}public Product getResult(){return product;}
}
// 具体建造者2
class ConcreteBuilder2 extends Builder {private Product product = new Product();public void buildPartA(){product.add("部件X");}public void buildPartB(){product.add("部件Y");}public Product getResult(){return product;}
}
指挥者
class Director{public void construct(Builder builder){builder.buildPartA();builder.buildPartB();}
}
客户端
客户端不需要知道具体的建造过程
public class Test {public static void main(String[] args){System.out.println("**********************************************"); System.out.println("《大话设计模式》代码样例");System.out.println(); Director director = new Director();Builder b1 = new ConcreteBuilder1();Builder b2 = new ConcreteBuilder2();//指挥者用ConcreteBuilder1的方法来建造产品director.construct(b1); //创建的是产品A和产品BProduct p1 = b1.getResult();p1.show();//指挥者用ConcreteBuilder2的方法来建造产品director.construct(b2); //创建的是产品X和产品YProduct p2 = b2.getResult();p2.show();System.out.println();System.out.println("**********************************************");}
}
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
下一篇:Lasso回归理论及代码实现