设计模式之建造者模式
程序员文章站
2022-03-26 13:31:16
题目:用程序画一个小人,简单点,要求是小人要有头、身体、两手、两脚就可以了。 第一版: 先造一支笔 再编写绘图类 一起来造人 人是造出来了,但造人的过程都是封装在子类中。如果现在要加个高个的黑人,我们有可能因为编程不注意,使其缺胳膊少腿。所以最好的方法是规定,凡是建造小人,都必须有头、有身体、有四肢 ......
题目:用程序画一个小人,简单点,要求是小人要有头、身体、两手、两脚就可以了。
第一版:
先造一支笔
public class Pen { private String color; public Pen(String color){ this.color = color; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
再编写绘图类
public class Graphics { public void drawEclipse(Pen p, int x, int y, int z, int w){ System.out.println("画头: " + p.getColor() + " : " + x + " : " + y + " : " + z + " : " + w); } public void drawRectangle(Pen p, int x, int y, int z, int w){ System.out.println("画身体: " + p.getColor() + " : " + x + " : " + y + " : " + z + " : " + w); } public void drawLine(Pen p, int x, int y, int z, int w){ System.out.println("画四肢: " + p.getColor() + " : " + x + " : " + y + " : " + z + " : " + w); } }
public class PersonFatBuilder { private Graphics g; private Pen p; public PersonFatBuilder(Graphics g, Pen p){ this.g = g; this.p = p; } public void build(){ g.drawEclipse(p, 50, 30, 30, 30); g.drawRectangle(p, 60, 60, 10, 50); g.drawLine(p,70, 50, 40, 100); g.drawLine(p, 80, 50, 90, 100); g.drawLine(p, 70, 100, 45, 150); g.drawLine(p, 80, 100, 85, 150); } }
public class PersonThinBuilder { private Graphics g; private Pen p; public PersonThinBuilder(Graphics g, Pen p){ this.g = g; this.p = p; } public void build(){ g.drawEclipse(p, 50, 20, 30, 30); g.drawRectangle(p, 60, 50, 10, 50); g.drawLine(p, 60, 50, 40, 100); g.drawLine(p, 70, 50, 90, 100); g.drawLine(p, 60, 100, 45, 150); g.drawLine(p, 70, 100, 85, 150); } }
一起来造人
public class Test { public static void main(String[] args){ System.out.println("画一个瘦黄人"); Pen p = new Pen("yellow"); Graphics gThin = new Graphics(); PersonThinBuilder thinBuilder = new PersonThinBuilder(gThin, p); thinBuilder.build(); System.out.println("画一个白胖纸"); Pen p1 = new Pen("white"); Graphics gFat = new Graphics(); PersonFatBuilder fatBuilder = new PersonFatBuilder(gFat, p1); fatBuilder.build(); } }
人是造出来了,但造人的过程都是封装在子类中。如果现在要加个高个的黑人,我们有可能因为编程不注意,使其缺胳膊少腿。所以最好的方法是规定,凡是建造小人,都必须有头、有身体、有四肢。这里我们就可以用到建造者模式了。
建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
public abstract class PersonBuilder { protected Graphics g; protected Pen p; public PersonBuilder(Graphics g, Pen p){ this.g = g; this.p = p; } public abstract void buildHead(); public abstract void buildBody(); public abstract void buildArmLeft(); public abstract void buildArmRight(); public abstract void buildLegLeft(); public abstract void buildLegRight(); }
public class PersonThinBuilder1 extends PersonBuilder{ public PersonThinBuilder1(Graphics g, Pen p){ super(g, p); } @Override public void buildHead() { // TODO Auto-generated method stub g.drawEclipse(p, 50, 20, 30, 30); } @Override public void buildBody() { // TODO Auto-generated method stub g.drawRectangle(p, 60, 50, 10, 50); } @Override public void buildArmLeft() { // TODO Auto-generated method stub g.drawLine(p, 60, 50, 40, 100); } @Override public void buildArmRight() { // TODO Auto-generated method stub g.drawLine(p, 70, 50, 90, 100); } @Override public void buildLegLeft() { // TODO Auto-generated method stub g.drawLine(p, 60, 100, 45, 150); } @Override public void buildLegRight() { // TODO Auto-generated method stub g.drawLine(p, 70, 100, 85, 150); } }
public 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(); } }
public class Test2 { public static void main(String[] args) { // TODO Auto-generated method stub Pen p = new Pen("red"); Graphics g= new Graphics(); PersonThinBuilder1 pb = new PersonThinBuilder1(g, p); PersonDirector pdThin = new PersonDirector(pb); pdThin.createPerson(); } }
PersonDirector类的目的就是根据用户的选择来一步一步地建造小人,而建造的过程在指挥者这里就完成了,用户就不需要知道了。由于这个过程的每一步都需要做的,就不会出现少画一只手,一条腿的情况。
建造者模式解析
基本代码:
public class Product { List<String> parts = new ArrayList<String>(); public void add(String part){ parts.add(part); } public void show(){ System.out.println("产品创建--------"); for(String part: parts){ System.out.print(part + " "); } } }
public abstract class Builder { public abstract void buildPartA(); public abstract void buildPartB(); public abstract Product getResult(); }
public class Director { public void construct(Builder builder){ builder.buildPartA(); builder.buildPartB(); } }
public class ConcreteBuilder1 extends Builder{ private Product product = new Product(); @Override public void buildPartA() { // TODO Auto-generated method stub product.add("部件A"); } @Override public void buildPartB() { // TODO Auto-generated method stub product.add("部件B"); } @Override public Product getResult() { // TODO Auto-generated method stub return product; } }
public class ConcreteBuilder2 extends Builder{ private Product product = new Product(); @Override public void buildPartA() { // TODO Auto-generated method stub product.add("部件X"); } @Override public void buildPartB() { // TODO Auto-generated method stub product.add("部件Y"); } @Override public Product getResult() { // TODO Auto-generated method stub return product; } }
public class Test3 { public static void main(String[] args) { // TODO Auto-generated method stub Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); director.construct(b1); Product p1 = b1.getResult(); p1.show(); System.out.println("\n--------------------------"); director.construct(b2); Product p2 = b2.getResult(); p2.show(); } }
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式。