设计模式之构造者模式

       构造者模式用于创建一个包含多个组成部分的复杂对象,可以返回一个完整的产品对象给用户。建造者模式关注该复杂对象时如何一步一步创建而成的,对于用户而言,无需知道创建过程和内部组成细节,只需直接使用创建好的完整对象即可。

模式动机:

无论在现实生活中还是在软件系统中,都存在一些复杂的对象,他们拥有多个组成部分,如汽车,他包括方向盘,车轮,发送机等各种部件,而对于大多数用户而言,无需知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一台完整的汽车,如图:

《设计模式之构造者模式》

在软件开发中,也存在大量类似汽车一样的复杂对象,他们拥有一系列成员属性,这些成员属性有些是引用类型的成员对象,而且在这些对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用,例如,一封电子邮件包括发件人,收件人,主题,内容,附件等,没有收件人则不能构造。此时,复杂对象相当于一台有待构造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无需关心该对象所包含的属性以及他们的组装方式,这就是建造者模式的动机。

模式定义:

  建造者模式builder pattern:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。构造者模式是一步一步创建一个复杂的对象,它允许用户只通过复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体细节。建造者模式属性对象创建型模式。

definition

《设计模式之构造者模式》Separate the construction of a complex object from its representation so that the same construction process can create different representations.

《设计模式之构造者模式》

Product:他包含多个组成部件,具体构建者创建该产品的内部表示并定义它的装配过程。

Builder:为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX()方法,他们用于创建复杂对象的各个部件,另一类方法是getResult()方法,用于返回复杂对象。

 

concreteBuilder:实现了builder的接口。也可以提供一个方法返回创建好的复杂产品对象。

Director:

 指挥者又称导演雷,他负责安装对象建造次序,。

个人感悟:

 如果细看,会发现builder pattern和策略模式很是相似,策略模式也是定义了一个接口的几种实现,然后调用时改变接口所指向的具体实例,只不过builder属于对象创建型模式,策略模式属于对象行为型模式

 

实例:

 建造者模式用于描述KFc如何创建套餐:套餐是一个复杂对象,他一般包含主食(如汉堡,鸡肉卷等)和饮料(如果汁、可乐等)等组成部分;不同的套餐有不同的组成部分,而KFC 的服务员可以根据顾客的要求,一步一步的装配这些组成部分,构造一个完整的套餐,然后返回给客户。

代码:

Product类:

public class Meal {
    //food 和drink是部件
    private String food;
    private String drink;
    public String getFood() {
        return food;
    }
    public void setFood(String food) {
        this.food = food;
    }
    public String getDrink() {
        return drink;
    }
    public void setDrink(String drink) {
        this.drink = drink;
    }
    public String toString()
    {
        return (food+drink);
        
    }
}

Builder类:

public abstract class MealBuilder {
    protected Meal meal=new Meal();
    
    public abstract void buildFood();
    public abstract void bulidDrink();
    
    public Meal getMeal()
    {
        return meal;
    }


}

这里的builder类有Product类的引用,子类就继承了Product。更上面的uml图中子类含有Procut类的引用不同。

具体构造者:

public class SubMealBuilderA extends MealBuilder{

    @Override
    public void buildFood() {
         meal.setFood("一个鸡腿堡");
        
    }

    @Override
    public void bulidDrink() {
         meal.setDrink("一杯可乐");
        
    }
}
public class SubMealBuilderB extends MealBuilder{

    @Override
    public void buildFood() {
        meal.setFood("一个鸡肉卷");
        
    }

    @Override
    public void bulidDrink() {
        meal.setDrink("一杯果汁");
    }
}

Director类:

public class KFCWaiter {
    private MealBuilder mb;
    public void setMealBuilder(MealBuilder mb)
    {
        this.mb=mb;
    }
    public Meal construct()
    {
        mb.buildFood();
        mb.bulidDrink();
        return mb.getMeal();
    }

}

测试类:

public class TestMain {

     
    public static void main(String[] args) {
        MealBuilder mb=new SubMealBuilderA();
        KFCWaiter waiter=new KFCWaiter();
        waiter.setMealBuilder(mb);
        Meal meal=waiter.construct();
        
        System.out.println(meal.getFood());
        System.out.println(meal.getDrink());
        
        mb=new SubMealBuilderB();
        waiter.setMealBuilder(mb);//一定要有这句,否则还是前面的
        Meal meal2=waiter.construct();
        System.out.println(meal2);
        System.out.println(meal2.getFood());
        System.out.println(meal2.getDrink());
    
    }

}

一个鸡腿堡
一杯可乐
一个鸡肉卷一杯果汁
一个鸡肉卷
一杯果汁

可以看出,跟换具体构造者无须修改。

 参考:http://www.dofactory.com/Patterns/PatternBuilder.aspx

 

建造者模式与工厂模式的区别

       我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。

       与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端

 

    原文作者:设计模式
    原文地址: http://www.cnblogs.com/youxin/archive/2013/05/21/3090262.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞