龙空技术网

设计模式之建造者模式

一个IT男的笔记 221

前言:

现在姐妹们对“如何在别人的服务器里开创造者模式”可能比较关心,我们都想要了解一些“如何在别人的服务器里开创造者模式”的相关内容。那么小编同时在网上搜集了一些对于“如何在别人的服务器里开创造者模式””的相关知识,希望朋友们能喜欢,你们快快来了解一下吧!

简介

建造者模式是分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况下使用。

由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。

应用场景:

java中的StringBuilder类的append方法;

SQL中的PreparedStatement;

JDOM中,DomBuilder、SAXBuilder;

Mybatis中用到的建造者模式:SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder等。

比如:XMLConfigBuilder读取配置文件构建出Configuration对象,然后SqlSessionFactoryBuilder使用Configuration对象作为参数,构建出SqlSessionFactory对象。

原因:这么做的原因是Mybatis的初始化工作较复杂,不是一个构造函数就能包括的。所以采用了分层构建方法。例如Mybatis中极其重要的Configuration对象,它庞大且复杂,初始化比较麻烦,所以使用专门的建造者XMLConfigBuilder进行构建。

建造者模式的优缺点:

优点:

封装性好,创建和使用分离;无需修改原有代码,符合“开闭原则”。

拓展性好,建造类之间独立,一定程度上解耦;代码解耦,模块化,方便维护。产品本身与创建过程解耦,可以使用相同的创建过程得到不同的产品。

缺点:

产品必须有共同点,使用范围有限。建造者模式创造出来的产品,其组成部分基本相同。如果产品之间的差异较大,则不适用这个模式。

若产品内部发生变化,建造者都要修改,成本较大;若内部变化复杂,会有很多的建造类。

与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

代码实现(举例说明)

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

整个过程大致可以分为5步:

第一,定义Product(产品角色): 一个具体的产品对象。

/** * 一个具体的产品对象,实体 */public class Meal {    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;    }}

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

/** * 抽象建造者 */public abstract class MealBuilder {    Meal meal = new Meal();    public abstract void buildFood();    public abstract void buildDrink();    public Meal getMeal(){        return meal;    }}

第三,定义ConcreteBuilder(具体建造者): 实现抽象接口,构建和装配各个部件。

/** * 具体建造者:A套餐 */public class MealA extends MealBuilder{    public void buildDrink() {        meal.setDrink("可乐");    }    public void buildFood() {        meal.setFood("薯条");    }}
/** * 具体建造者:B套餐 */public class MealB extends MealBuilder{    public void buildDrink() {        meal.setDrink("柠檬果汁");    }    public void buildFood() {        meal.setFood("鸡翅");    }}

第四,定义Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。

/** * 指挥者:构建一个使用Builder接口的对象 */public class KFCServer {    private MealBuilder mealBuilder;    public KFCServer(MealBuilder mealBuilder) { //构造方法        this.mealBuilder = mealBuilder;    }    public Meal construct(){        //准备食物        mealBuilder.buildFood();        //准备饮料        mealBuilder.buildDrink();        //准备完毕,返回一个完整的套餐给客户        return mealBuilder.getMeal();    }}

第五,定义测试类:

/** * 测试类 */public class Test {    public static void main(String[] args) {        MealA a = new MealA();//创建套餐A对象        KFCServer waitera = new KFCServer(a);//准备套餐A的服务员        Meal mealA = waitera.construct();//获得套餐A        System.out.print("套餐A的组成部分:");        System.out.println("食物:"+mealA.getFood()+";   "+"饮品:"+mealA.getDrink());        MealB b = new MealB();        KFCServer waiterb = new KFCServer(b);        Meal mealB = waiterb.construct();        System.out.print("套餐B的组成部分:");        System.out.println("食物:"+mealB.getFood()+";   "+"饮品:"+mealB.getDrink());    }}

标签: #如何在别人的服务器里开创造者模式