引入        

        用笔画一个个小人,形状各异,要求小人有胳膊、身体、头部、手脚就可以。但是直接这样去编程有时候会因为疏忽忘记,出现缺手缺脚的情况,就说明这种建造方式不是稳定的。

一、定义

建造者模式(Builder)将一个复杂对象的创建和它的表示方法分离,使得同样的构建过程可以创建不同的表示。

二、组成:

1、Product产品类:具体产品

2、Builder抽象建造者:为了建造一个Product对象的各个部件指定的抽象接口。

3、ConcreteBuilder具体建造者:实现Builder接口,构造和装配各个部件。

4、Director导演类:构建一个Builder接口对象。

UML类图:

java两个小人亲的代码 用java绘制小人_设计模式

 建造者模式基本代码:

Product类——产品类,有由多个部件组成

public class Product {
    List<String> parts=new ArrayList<String>();
    public void Add(String part){
        parts.add(part);
    }
    public void display(){
        System.out.println("\n产品创建");
        for(String s: parts){
            System.out.println(s);
        }
    }
}

 Builder类——抽象建造者,确定产品由两个部件A和B组成,并声明一个得到产品建造后结果的方法getProduct.

public abstract class Builder {
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getProduct();
}

ConcereteBuilder1——具体建造者类

public class ConcreteBuilder1 extends Builder {
    private Product product=new Product();

    @Override
    public void buildPartA() {
        product.Add("部件A");
    }

    @Override
    public void buildPartB() {
        product.Add("部件B");
    }

    public Product getProduct() {
        return product;
    }
}

ConcereteBuilde2——具体建造者类

public class ConcreteBuilder2 extends Builder {
    private Product product=new Product();

    @Override
    public void buildPartA() {
        product.Add("部件C");
    }

    @Override
    public void buildPartB() {
        product.Add("部件D");
    }

    public Product getProduct() {
        return product;
    }
}

Director类——指挥者类。

public class Director {
    public void ConStruct(Builder builder){
        builder.buildPartA();
        builder.buildPartB();
    }
}

测试类

public class Demo {
    public static void main(String[] args) {
        Director director = new Director();
        Builder b1 = new ConcreteBuilder1();
        Builder b2 = new ConcreteBuilder2();

        director.ConStruct(b1);
        b1.getProduct().display();

        director.ConStruct(b2);
        b2.getProduct().display();
    }
}

三、具体场景示例(画火柴人)

1、GUI绘图的相关 Java类介绍

  • JFrame类,是Java图形用户界面(GUI)工具包swing中的存放组件的容器。相当于相框。
  • JPanel类,是Java图形用户界面(GUI)工具包swing中的面板容器类。相当于画板。
  • Graphics类,是Java用于绘图和显示格式化文字的工具。相当于画笔。

2、代码实现 

抽象建造者PersonBuilder类

public abstract class PersonBuilder {
    protected Graphics graphics;

    public PersonBuilder(Graphics graphics) {
        this.graphics = graphics;
    }

    public abstract void BuildHead();

    public abstract void BuildBody();

    public abstract void BuildArmLeft();

    public abstract void BuildArmRight();

    public abstract void BuildLegLeft();

    public abstract void BuildLegRight();
}

具体建造者类PersonJumpBuilder

/**
 * 跳跃的火柴人
 */
public class PersonJumpBuilder extends PersonBuilder {
    public PersonJumpBuilder(Graphics graphics) {
        super(graphics);
    }

    @Override
    public void BuildHead() {
        // 头部
        graphics.fillOval(100, 70, 30, 30);
    }

    @Override
    public void BuildBody() {
        // 身体
        graphics.drawLine(115, 100, 115, 140);
    }

    @Override
    public void BuildArmLeft() {
        // 左臂
        graphics.drawLine(115, 105, 70, 90);
    }

    @Override
    public void BuildArmRight() {
        // 右臂
        graphics.drawLine(115, 105, 160, 90);
    }

    @Override
    public void BuildLegLeft() {
        // 左腿
        graphics.drawLine(115, 140, 55, 150);
    }

    @Override
    public void BuildLegRight() {
        // 右腿
        graphics.drawLine(115, 140, 175, 150);
    }
}

具体建造者类PersonRunBuilder

/**
 * 奔跑的火柴人
 */
public class PersonRunBuilder extends PersonBuilder {
    public PersonRunBuilder(Graphics graphics) {
        super(graphics);
    }

    @Override
    public void BuildHead() {
        // 头部
        graphics.fillOval(100, 70, 30, 30);
    }

    @Override
    public void BuildBody() {
        // 身体
        graphics.drawLine(115, 95, 100, 160);
    }

    @Override
    public void BuildArmLeft() {
        // 左臂
        graphics.drawLine(115, 105, 95, 105);
        graphics.drawLine(95, 105, 85, 130);
    }

    @Override
    public void BuildArmRight() {
        // 右臂
        graphics.drawLine(115, 105, 125, 130);
        graphics.drawLine(125, 130, 150, 130);
    }

    @Override
    public void BuildLegLeft() {
        // 左腿
        graphics.drawLine(95, 160, 70, 160);
    }

    @Override
    public void BuildLegRight() {
        // 右腿
        graphics.drawLine(105, 140, 120, 150);
        graphics.drawLine(120, 150, 120, 190);
    }
}

指挥者类PersonDirector

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 Demo {
    public static void main(String[] args) {
        // 创建窗口对象
        JFrame frame = new JFrame();
        frame.setVisible(true);
        frame.setTitle("画人");
        frame.setSize(280, 300);

        // 设置窗口关闭按钮的默认操作(点击关闭时退出进程)
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // 把窗口位置设置到屏幕的中心
        frame.setLocationRelativeTo(null);
        frame.setContentPane(new JPanel(){
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                BasicStroke stokeLine = new BasicStroke(6.0f);
                Graphics2D g2=(Graphics2D) g;
                g2.setStroke(stokeLine);
                PersonBuilder pb = new PersonRunBuilder(g2);
                /*PersonBuilder pb = new PersonJumpBuilder(g2);*/
                PersonDirector director = new PersonDirector(pb);
                director.createPerson();
            }
        });
    }
}

效果展示 

java两个小人亲的代码 用java绘制小人_设计模式_02

        

java两个小人亲的代码 用java绘制小人_gui_03

 四、模式用途

         当我们需要将一个复杂的对象的构建与它的表示分离,是的同样的构建过程可以创建不同的表示,需要使用到建造者模式。它将产品的内部表象与产品的生成过程分割开来,从而可以使得一个构造过程声称具有不同的内部表象的产品。因此用户只需要指定需要构造的类型就可以得到他们,而具体的构造过程和细节就不需要知道了。同时也满足开闭原则,若需改变产品外观,只需要在定义一个具体建造者类就可以了。