设计模式-建造者模式(9)

建造者模式(Builder Pattern) 也叫做生成器模式。将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。

建造者模式的优点
●封装性
使用建造者模式可以使客户端不必知道产品内部组成的细节, 如例子中我们就不需要关心每一个具体的模型内部是如何实现的, 产生的对象类型就是CarModel。
● 建造者独立, 容易扩展
BenzBuilder和BMWBuilder是相互独立的, 对系统的扩展非常有利。
● 便于控制细节风险
由于具体的建造者是独立的, 因此可以对建造过程逐步细化, 而不对其他的模块产生任何影响。

建造者模式的使用场景
● 相同的方法, 不同的执行顺序, 产生不同的事件结果时, 可以采用建造者模式。
● 多个部件或零件, 都可以装配到一个对象中, 但是产生的运行结果又不相同时, 则可以使用该模式。
● 产品类非常复杂, 或者产品类中的调用顺序不同产生了不同的效能, 这个时候使用建造者模式非常合适。
● 在对象创建过程中会使用到系统中的一些其他对象, 这些对象在产品对象的创建过程中不易得到时, 也可以采用建造者模式封装该对象的创建过程。 该种场景只能是一个补偿方法, 因为一个对象不容易获得, 而在设计阶段竟然没有发觉, 而要通过创建者模式柔化创建过程, 本身已经违反设计的最初目标。
 

建造者模式的注意事项
建造者模式关注的是零件类型和装配工艺(顺序) , 这是它与工厂方法模式最大不同的地方, 虽然同为创建类模式, 但是注重点不同。大家看到这里估计就开始犯嘀咕了, 这个建造者模式和工厂模式非常相似呀, 是的, 非常相似, 但是记住一点你就可以游刃有余地使用了: 建造者模式最主要的功能是基本方法的调用顺序安排, 也就是这些基本方法已经实现了, 通俗地说就是零件的装配, 顺序不同产生的对象也不同; 而工厂方法则重点是创建, 创建零件是它的主要职责, 组装顺序则不是它关
心的。

 

建造者模式的扩展
建造者模式中还有一个角色没有说明, 就是零件, 建造者怎么去建造一个对象? 是零件的组装, 组装顺序不同对象效能也不同, 这才是建造者模式要表达的核心意义, 而怎么才能更好地达到这种效果呢? 引入模板方法模式是一个非常简单而有
效的办法。

 

建造者模式的实现方式

下面以肯德基餐厅食物和麦当劳餐厅食物为例,利用建造者模式根据不同的食品组合创建创建套餐。

PackageDirector :食物套餐组合

Food:食物

Builder: 抽象食物建造者

KFCBuilder:肯德基食物建造者

MacDonaldBuilder:麦当劳食物建造者
/**
* @Title: Builder
* @Description: 餐厅
* @author chy
* @date 2018/5/14 11:18
*/
public abstract class Builder {

    /**
     *  汉堡包
     */
    public abstract void builderHamburger();

    /**
     *  可乐
     */
    public abstract void builderCola();

    /**
     * 薯条
     */
    public abstract void builderFries();

    /**
     * 鸡块
     */
    public abstract void builderChicken();

    /**
     * 获取套餐信息
     * @return
     */
    public abstract Food getPackage();

    /**
     * 清理信息
     * @return
     */
    public abstract void clear();
}
/**
* @Title: KFCBuilder
* @Description: KFC餐厅
* @author chy
* @date 2018/5/14 11:19
*/
public class KFCBuilder extends Builder {

    private  Food food=new Food();

    @Override
    public void builderHamburger() {
        food.add("肯德基汉堡包");
    }

    @Override
    public void builderCola() {
        food.add("可口可乐");
    }

    @Override
    public void builderFries() {
        food.add("肯德基薯条");
    }

    @Override
    public void builderChicken() {
        food.add("肯德基鸡块");
    }

    @Override
    public Food getPackage() {
        return food;
    }

    @Override
    public void clear() {
        food.clear();
    }
}
/**
 * @Title: KFCBuilder
 * @Description: 麦当劳餐厅
 * @author chy
 * @date 2018/5/14 11:19
 */
public class MacDonaldBuilder extends  Builder {

    private  Food food=new Food();

    @Override
    public void builderHamburger() {
        food.add("麦当劳汉堡包");
    }

    @Override
    public void builderCola() {
        food.add("百事可乐");
    }

    @Override
    public void builderFries() {
        food.add("麦当劳薯条");
    }

    @Override
    public void builderChicken() {
        food.add("麦当劳鸡块");
    }

    @Override
    public Food getPackage() {
        return food;
    }

    @Override
    public void clear() {
        food.clear();
    }

}
/**
* @Title: Food
* @Description: 食物
* @author chy
* @date 2018/5/14 11:17
*/
public class Food {

    List<String> items = new ArrayList();

    public void add(String part) {
        items.add(part);
    }

    public void clear() {
        items.clear();
    }

    public void show() {
        System.out.println("套餐内容:");
        for (int i = 0; i < items.size(); i++) {
            System.out.println(items.get(i));
        }
    }

}
/**
* @Title: PackageDirector
* @Description: 组装套餐
* @author chy
* @date 2018/5/14 11:28
*/
public class PackageDirector {

    /**
     * 肯德基套餐A 模版
     * @param kfc
     */
    public void packageKFCA(Builder kfc){
        kfc.clear();
        kfc.builderCola();
        kfc.builderChicken();
    }

    /**
     * 肯德基套餐B 模版
     * @param kfc
     */
    public void packageKFCB(Builder kfc){
        kfc.clear();
        kfc.builderFries();
        kfc.builderHamburger();
    }

    /**
     * 麦当劳套餐A 模版
     * @param mdn
     */
    public void packageMDNA(Builder mdn){
        mdn.clear();
        mdn.builderHamburger();
        mdn.builderCola();
    }

    /**
     * 麦当劳套餐B 模版
     * @param mdn
     */
    public void packageMDNB(Builder mdn){
        mdn.clear();
        mdn.builderFries();
        mdn.builderChicken();
    }
}
/**
* @Title: Client
* @Description: 建造者模式: 适用于一些基本部件不会变,而其组合经常变化的场景
  关键词:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
  比如:肯德基和麦当劳  产品薯条,可乐,鸡块,汉堡  都有套餐A和套餐B
* @author chy
* @date 2018/5/14 10:51
*/
public class Client {

   public static  void main(String[] arg) {

     //负责指挥套餐食物种类(套餐模版已经规定好食物的顺序和种类)
     PackageDirector director = new PackageDirector();

     //肯德基食物创建者
     KFCBuilder kfc = new KFCBuilder();

     //肯德基食物创建者
     MacDonaldBuilder mdn = new MacDonaldBuilder();

     Food food = null;

     //选择肯德基A套餐
     director.packageKFCA(kfc);

     //组装肯德基A套餐食物
     food = kfc.getPackage();

     //打印食物信息
     food.show();

     //选择麦当劳B套餐
     director.packageMDNB(mdn);

     //组装麦当劳B套餐食物
     food = mdn.getPackage();

     //打印食物信息
     food.show();
   }

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值