建造者模式

文章参考书籍:重学Java设计模式
作者:⼩傅哥

场景:
模拟装修公司对于设计出⼀些套餐装修服务的。
很多装修公司都会给出⾃家的套餐服务,⼀般有;欧式豪华、轻奢⽥园、现代简约等等,⽽这些套餐的后⾯是不同的商品的组合。例如;⼀级&⼆级吊顶、多乐⼠涂料、圣象地板、⻢可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,最终再按照装修⾯积给出⼀个整体的报价。这⾥我们就模拟装修公司想推出⼀些套餐装修服务,按照不同的价格设定品牌选择组合

建造者模式_第1张图片
image.png

传统方式实现

物料接口

import java.math.BigDecimal;

/**
 * 物料接口
 * 提供物料的基本信息
 */
public interface Matter {

    /**
     * 场景:地板、地砖、吊顶、涂料
     * @return
     */
    String scene();

    /**
     * 品牌
     * @return
     */
    String brand();

    /**
     * 型号
     * @return
     */
    String model();

    /**
     * 价格
     * @return
     */
    BigDecimal price();

    /**
     * 描述
     * @return
     */
    String desc();
}

一级吊顶

import com.ustcinfo.strategy.Matter;

import java.math.BigDecimal;

/**
 * 一级吊顶
 */
public class LevelOneCeiling implements Matter {
    @Override
    public String scene() {
        return "吊顶";
    }

    @Override
    public String brand() {
        return "装修公司自带";
    }

    @Override
    public String model() {
        return "一级顶";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(200);
    }

    @Override
    public String desc() {
        return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
    }
}

二级吊顶

import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;

/**
 * 二级吊顶
 */
public class LevelTwoCeiling implements Matter {
    @Override
    public String scene() {
        return "吊顶";
    }

    @Override
    public String brand() {
        return "装修公司自带";
    }

    @Override
    public String model() {
        return "二级顶";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(800);
    }

    @Override
    public String desc() {
        return "两个层次的吊顶,⼆级吊顶⾼度⼀般就往下吊20cm,要是层⾼很⾼,也可增加\n" +
                "每级的厚度";
    }
}

涂料-多乐士

import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;

/**
* 涂料 多乐士
*/
public class DuluxCoat implements Matter {
   @Override
   public String scene() {
       return "涂料";
   }

   @Override
   public String brand() {
       return "多乐士";
   }

   @Override
   public String model() {
       return "第二代";
   }

   @Override
   public BigDecimal price() {
       return new BigDecimal(700);
   }

   @Override
   public String desc() {
       return "多乐⼠是阿克苏诺⻉尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国\n" +
               "家,每年全球有5000万户家庭使⽤多乐⼠油漆。";
   }
}

涂料-立邦

import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;

/**
 * 涂料 立邦
 */
public class LiBangCoat implements Matter {
    @Override
    public String scene() {
        return "涂料";
    }

    @Override
    public String brand() {
        return "立邦";
    }

    @Override
    public String model() {
        return "默认级别";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(600);
    }

    @Override
    public String desc() {
        return "⽴邦始终以开发绿⾊产品、注᯿⾼科技、⾼品质为⽬标,以技术⼒量不断推进科\n" +
                "研和开发,满⾜消费者需求。";
    }
}

地板-德尔

import java.math.BigDecimal;
/**
 * 地板 德尔
 */
public class DerFloor implements Matter {
    @Override
    public String scene() {
        return "地板";
    }

    @Override
    public String brand() {
        return "德尔";
    }

    @Override
    public String model() {
        return "A+";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(120);
    }

    @Override
    public String desc() {
        return "DER德尔集团是全球领先的专业⽊地板制造商,北京2008年奥运会家装和公装\n" +
                "地板供应商";
    }
}

地板-圣象

import java.math.BigDecimal;

/**
 * 地板 圣象
 */
public class ShengXiangFloor implements Matter {
    @Override
    public String scene() {
        return "地板";
    }

    @Override
    public String brand() {
        return "圣象";
    }

    @Override
    public String model() {
        return "一级";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(310);
    }

    @Override
    public String desc() {
        return "圣象地板是中国地板⾏业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国\n" +
                "家免检、中国环境标志认证等多项荣誉。";
    }
}

地砖-东鹏

import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;

/**
 * 地砖 东鹏
 */
public class DongPengTile implements Matter {
    @Override
    public String scene() {
        return "地砖";
    }

    @Override
    public String brand() {
        return "东鹏瓷砖";
    }

    @Override
    public String model() {
        return "10001";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(102);
    }

    @Override
    public String desc() {
        return "东鹏瓷砖以品质铸就品牌,科技推动品牌,⼝碑传播品牌为宗旨,2014年品牌\n" +
                "价值132.35亿元,位列建陶⾏业榜⾸。";
    }
}

地砖-马可波罗

package com.ustcinfo.strategy.tile;
import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;

/**
 * 地砖 马可波罗
 */
public class MarcoPoloTile implements Matter {
    @Override
    public String scene() {
        return "地砖";
    }

    @Override
    public String brand() {
        return "马可波罗";
    }

    @Override
    public String model() {
        return "缺省";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(140);
    }

    @Override
    public String desc() {
        return "⻢可波罗品牌诞⽣于1996年,作为国内最早品牌化的建陶品牌,以“⽂化陶\n" +
                "瓷”占领市场,享有“仿古砖⾄尊”的美誉。";
    }
}

测试及运行结果

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class DecorationPackageController {

    public static String decoration(BigDecimal area, Integer level) {
        List list = new ArrayList(); // 装修清单
        BigDecimal price = BigDecimal.ZERO; // 装修价格
        // 豪华欧式
        if (1 == level) {
            LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊顶,⼆级顶
            DuluxCoat duluxCoat = new DuluxCoat(); // 涂 料,多乐⼠
            ShengXiangFloor shengXiangFloor = new ShengXiangFloor(); // 地板,圣象
            list.add(levelTwoCeiling);
            list.add(duluxCoat);
            list.add(shengXiangFloor);
            price = price.add(area.multiply(new
                    BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
            price = price.add(area.multiply(new
                    BigDecimal("1.4")).multiply(duluxCoat.price()));
            price = price.add(area.multiply(shengXiangFloor.price()));
        }
        // 轻奢⽥园
        if (2 == level) {
            LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊顶,⼆级顶
            LiBangCoat liBangCoat = new LiBangCoat(); // 涂料,⽴邦
            MarcoPoloTile marcoPoloTile = new MarcoPoloTile(); // 地砖,⻢可波罗
            list.add(levelTwoCeiling);
            list.add(liBangCoat);
            list.add(marcoPoloTile);
            price = price.add(area.multiply(new
                    BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
            price = price.add(area.multiply(new
                    BigDecimal("1.4")).multiply(liBangCoat.price()));
            price = price.add(area.multiply(marcoPoloTile.price()));
        }
        // 现代简约
        if (3 == level) {
            LevelOneCeiling levelOneCeiling = new LevelOneCeiling(); //吊顶,⼆级顶
            LiBangCoat liBangCoat = new LiBangCoat(); //涂料,⽴邦
            DongPengTile dongPengTile = new DongPengTile(); //地砖,东鹏
            list.add(levelOneCeiling);
            list.add(liBangCoat);
            list.add(dongPengTile);
            price = price.add(area.multiply(new
                    BigDecimal("0.2")).multiply(levelOneCeiling.price()));
            price = price.add(area.multiply(new
                    BigDecimal("1.4")).multiply(liBangCoat.price()));
            price = price.add(area.multiply(dongPengTile.price()));
        }
        StringBuilder detail = new StringBuilder("\r\n-------------------------------------------------------\r\n" +
                "装修清单" + "\r\n" +
                "套餐等级:" + level + "\r\n" +
                "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
                "房屋⾯积:" + area.doubleValue() + " 平⽶\r\n" +
                "材料清单:\r\n");
        for(Matter matter:list) {
            detail.append(matter.scene()).append(":")
                    .append(matter.brand()).append("、")
                    .append(matter.model()).append("、平⽶价格:")
                    .append(matter.price()).append(" 元。\n");
        }
        return detail.toString();
    }

    public static void main(String[] args) {
        System.out.println(decoration(new BigDecimal(120.0), 1));
        System.out.println(decoration(new BigDecimal(97.0), 2));
        System.out.println(decoration(new BigDecimal(85.0), 3));

    }
}

-------------------------------------------------------
装修清单
套餐等级:1
套餐价格:174000.00 元
房屋⾯积:120.0 平⽶
材料清单:
吊顶:装修公司自带、二级顶、平⽶价格:800 元。
涂料:多乐士、第二代、平⽶价格:700 元。
地板:圣象、一级、平⽶价格:310 元。


-------------------------------------------------------
装修清单
套餐等级:2
套餐价格:110580.00 元
房屋⾯积:97.0 平⽶
材料清单:
吊顶:装修公司自带、二级顶、平⽶价格:800 元。
涂料:立邦、默认级别、平⽶价格:600 元。
地砖:马可波罗、缺省、平⽶价格:140 元。


-------------------------------------------------------
装修清单
套餐等级:3
套餐价格:83470.00 元
房屋⾯积:85.0 平⽶
材料清单:
吊顶:装修公司自带、一级顶、平⽶价格:200 元。
涂料:立邦、默认级别、平⽶价格:600 元。
地砖:东鹏瓷砖、10001、平⽶价格:102 元。

建造者模式

建造者模式_第2张图片
image.png

IMenu

public interface IMenu {
    /**
     * 吊顶
     * @param matter
     * @return
     */
    IMenu appendCeiling(Matter matter);

    /**
     * 涂料
     * @param matter
     * @return
     */
    IMenu appendCoat(Matter matter);

    /**
     * 地板
     * @param matter
     * @return
     */
    IMenu appendFloor(Matter matter);

    /**
     * 地砖
     * @param matter
     * @return
     */
    IMenu appendTile(Matter matter);

    /**
     * 明细
     * @return
     */
    String getDetail();
}

DecorationPackageMenu

是 IMenu 接⼝的实现类,主要是承载建造过程中的填充器。相当于
这是⼀套承载物料和创建者中间衔接的内容。

public class DecorationPackageMenu implements IMenu {
    // 装修清单
    private List list = new ArrayList();
    // 装修价格
    private BigDecimal price = BigDecimal.ZERO;

    /**
     * ⾯积
     */
    private BigDecimal area;
    /**
     * 装修等级;豪华欧式、轻奢⽥园、现代简约
     */
    private String grade;
    private DecorationPackageMenu() {
    }
    public DecorationPackageMenu(Double area, String grade) {
        this.area = new BigDecimal(area);
        this.grade = grade;
    }
    public IMenu appendCeiling(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new
                BigDecimal("0.2")).multiply(matter.price()));
        return this;
    }
    public IMenu appendCoat(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new
                BigDecimal("1.4")).multiply(matter.price()));
        return this;
    }
    public IMenu appendFloor(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }
    public IMenu appendTile(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }

    /**
     * 明细
     * @return
     */
    public String getDetail() {
        StringBuilder detail = new StringBuilder("\r\n-------------------- -----------------------------------\r\n" + "装修清单" + "\r\n" + "套餐等级:" + grade + "\r\n" + "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) +
                " 元\r\n" + "房屋⾯积:" + area.doubleValue() + " 平⽶\r\n" + "材料清单:\r\n");
        for (Matter matter: list) {
            detail.append(matter.scene()).append(":").append(matter.brand()).append( "、").append(matter.model()).append("、平⽶价格:").append(matter.price()).append(" 元。\n");
        }
        return detail.toString();
    }
}

Builder

建造者类具体的各种组装由此类实现

public class Builder {
    public IMenu levelOne(Double area) {
        return new DecorationPackageMenu(area, "豪华欧式")
                .appendCeiling(new LevelTwoCeiling()) // 吊顶,⼆级顶
                .appendCoat(new DuluxCoat()) // 涂料,多乐⼠
                .appendFloor(new ShengXiangFloor()); // 地板,圣象
    }
    public IMenu levelTwo(Double area){
        return new DecorationPackageMenu(area, "轻奢⽥园")
                .appendCeiling(new LevelTwoCeiling()) // 吊顶,⼆级顶
                .appendCoat(new LiBangCoat()) // 涂料,⽴邦
                .appendTile(new MarcoPoloTile()); // 地砖,⻢可波罗
    }
    public IMenu levelThree(Double area){
        return new DecorationPackageMenu(area, "现代简约")
                .appendCeiling(new LevelOneCeiling()) // 吊顶,⼆级顶
                .appendCoat(new LiBangCoat()) // 涂料,⽴邦
                .appendTile(new DongPengTile()); // 地砖,东鹏
    }
}

测试及测试结果

public class Test_Builder {

    public static void main(String[] args) {
        Builder builder = new Builder();
        // 豪华欧式
        System.out.println(builder.levelOne(132.52D).getDetail());
        // 轻奢⽥园
        System.out.println(builder.levelTwo(98.25D).getDetail());
        // 现代简约
        System.out.println(builder.levelThree(85.43D).getDetail());
    }
}
测试结果:
-------------------- -----------------------------------
装修清单
套餐等级:豪华欧式
套餐价格:192154.00 元
房屋⾯积:132.52 平⽶
材料清单:
吊顶:装修公司自带、二级顶、平⽶价格:800 元。
涂料:多乐士、第二代、平⽶价格:700 元。
地板:圣象、一级、平⽶价格:310 元。
-------------------- -----------------------------------
装修清单
套餐等级:轻奢⽥园
套餐价格:112005.00 元
房屋⾯积:98.25 平⽶
材料清单:
吊顶:装修公司自带、二级顶、平⽶价格:800 元。
涂料:立邦、默认级别、平⽶价格:600 元。
地砖:马可波罗、缺省、平⽶价格:140 元。


-------------------- -----------------------------------
装修清单
套餐等级:现代简约
套餐价格:83892.26 元
房屋⾯积:85.43 平⽶
材料清单:
吊顶:装修公司自带、一级顶、平⽶价格:200 元。
涂料:立邦、默认级别、平⽶价格:600 元。
地砖:东鹏瓷砖、10001、平⽶价格:102 元。

总结: 当⼀些基本物料不会变,⽽其组合经常变化的时候 ,就可以选择这样的设计模式来构建代码

你可能感兴趣的:(建造者模式)