设计模式(九):建造者模式

来源:互联网 发布:去水印软件免费版 编辑:程序博客网 时间:2024/06/11 21:28

鱼香肉丝是一道众所周知的菜,然而不同师傅做出来的味道却千差万别,同样,M记、KFC之类的快餐店也遍布全国各地,但是在每个地方买到的吃起来味道却都一样,原因是它们有非常规范的制作流程,所有的门店都严格按照流程执行,所以不管在哪里吃起来味道都一样。鱼香肉丝这道菜每个师傅都有自己的做法,所以有各种口味的鱼香肉丝。


下面引入一个设计模式:

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。


结构图:


(1)Builder:建造者,为创建一个Product对象的各个部件指定的抽象接口。

(2)ConcreteBuilder:具体建造者,构造和装配各个部件

(3)Director:指挥者,包含一个建造者的引用,并将构建和装配各个部件的过程封装在一个方法中,客户端告诉指挥者需要建造什么类型的对象,由指挥者调用方法完成构建。

(4)Product:具体产品,当业务复杂时,可以将产品的构建步骤放入Product,在ConcreteBuilder中只需创建一个队Product对象的引用,然后向产品中添加每个部件。


建造者模式好处:使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以如果需要改变一个产品的内部表示,只需要再定义一个具体的建造者即可。

当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时使用建造者模式。


以KFC制作汉堡的流程来写一个例子:

假设制作一个汉堡需要面包、肉、生菜和沙拉,不同类型的汉堡只有肉的种类不一样

1、创建建造者

/** * Builder建造者,汉堡建造者类 */public abstract class Builder {    /**     * 面包     */    public abstract void buildBread();    /**     * 肉     */    public abstract void buildMeet();    /**     * 生菜     */    public abstract void buildLettuce();    /**     * 沙拉     */    public abstract void buildSalad();    /**     * 获取产品类     * @return     */    public abstract Product getHamburgerProduct();}

2、产品者

/** * 产品类,汉堡产品 */public class Product {    private List<String> parts=new ArrayList<String>();//构造汉堡的所有部件集合    /**     * 为产品添加每个部件     * @param part     */    public void add(String part){        parts.add(part);    }    /**     * 展示产品的创建     */    public void show(){        System.out.println("开始创建产品:");        for (int i=0;i<parts.size();i++){            System.out.println("建造part"+(i+1)+":"+parts.get(i));        }    }}


3、具体建造者

(1)鸡腿堡类

/** * ConcreteBuilder,具体建造者,鸡腿堡类 */public class ChikenHambugerBuilder extends Builder{    private Product product =new Product();//引用一个产品类    @Override    public void buildBread() {        product.add("两块面包");//添加构建的部件    }    @Override    public void buildMeet() {        product.add("一块鸡肉");    }    @Override    public void buildLettuce() {        product.add("一片生菜");    }    @Override    public void buildSalad() {        product.add("挤点沙拉");    }    public Product getHamburgerProduct() {        return product;    }}

(2)鳕鱼堡类

/** * ConcreteBuilder,具体建造者,鳕鱼堡类 */public class FishHambugerBuilder extends Builder {    private Product product =new Product();//引用一个产品类    @Override    public void buildBread() {        product.add("两块面包");    }    @Override    public void buildMeet() {        product.add("一块鳕鱼");    }    @Override    public void buildLettuce() {        product.add("一片生菜");    }    @Override    public void buildSalad() {        product.add("挤点沙拉");    }    public Product getHamburgerProduct() {        return product;    }}

4、创建指挥者,由指挥者执行产品构建的一系列流程

/** * 指挥者 */public class Director {    /**     * 指挥构建的开始     * @param builder     */    public void construct(Builder builder){        builder.buildBread();        builder.buildMeet();        builder.buildLettuce();        builder.buildSalad();    }}

5、客户端

public class Test {    public static void main(String[] args) {        //制作一个鸡腿堡        ChikenHambugerBuilder chikenHamburgerBuilder=new ChikenHambugerBuilder();        //创建指挥者        Director director=new Director();        director.construct(chikenHamburgerBuilder);//由指挥者开始构建        //创建产品者        Product product=chikenHamburgerBuilder.getHamburgerProduct();        product.show();//展示构建过程    }}

运行结果:

开始创建产品:建造part1:两块面包建造part2:一块鸡肉建造part3:一片生菜建造part4:挤点沙拉



根据大话设计模式中改写的另一个例子:

1、建造者抽象类PersonBuilder,用来构建一个人物模型

/** * Builder建造者 */public abstract class PersonBuilder {    /**     * 构建头部     */    public abstract void buildHead();    /**     * 构建身体     */    public abstract void buildBody();    /**     * 构建左胳膊     */    public abstract void buildArmLeft();    /**     * 构建右胳膊     */    public abstract void buildArmRight();    /**     * 构建左腿     */    public abstract void buildLegLeft();    /**     * 构建右腿     */    public abstract void buildLegRight();}

2、具体的建造者,继承建造者PersonBuilder

(1)女孩构建者

/** * 具体的构建者 */public class GirlBuilder extends PersonBuilder{    public void buildHead() {        System.out.println("构建女孩的头部");    }    public void buildBody() {        System.out.println("构建女孩的身体");    }    public void buildArmLeft() {        System.out.println("构建女孩的左胳膊");    }    public void buildArmRight() {        System.out.println("构建女孩的右胳膊");    }    public void buildLegLeft() {        System.out.println("构建女孩的左腿");    }    public void buildLegRight() {        System.out.println("构建女孩的右腿");    }}


(2)男孩构建者

/** * 具体的构建者 */public class BoylBuilder extends PersonBuilder{    public void buildHead() {        System.out.println("构建男孩的头部");    }    public void buildBody() {        System.out.println("构建男孩的身体");    }    public void buildArmLeft() {        System.out.println("构建男孩的左胳膊");    }    public void buildArmRight() {        System.out.println("构建男孩的右胳膊");    }    public void buildLegLeft() {        System.out.println("构建男孩的左腿");    }    public void buildLegRight() {        System.out.println("构建男孩的右腿");    }}

3、指挥者

/** * 指挥者 */public class PersonDirector {    private PersonBuilder personBuilder;    public PersonDirector(PersonBuilder personBuilder) {//用户告诉指挥者,构造具体的人        this.personBuilder = personBuilder;    }    public void createPerson(){//指挥者将构建的所有步骤封装在一个方法中        personBuilder.buildHead();        personBuilder.buildBody();        personBuilder.buildArmLeft();        personBuilder.buildArmRight();        personBuilder.buildLegLeft();        personBuilder.buildLegRight();    }}

4、客户端

public class Test {    public static void main(String[] args) {        GirlBuilder girlBuilder=new GirlBuilder();//创建一个女孩对象        PersonDirector personDirector=new PersonDirector(girlBuilder);//指挥者根据需求去创建        personDirector.createPerson();    }}


运行结果:

构建女孩的头部构建女孩的身体构建女孩的左胳膊构建女孩的右胳膊构建女孩的左腿构建女孩的右腿

来自:大话设计模式

原创粉丝点击