设计模式四:创建型-建造者模式

创建型模式:建造者模式

文章目录

建造者模式

1、建造者模式:介绍

  • 建造者模式
    • 核心目的是:通过使用多个简单对象一步步地构建出一个复杂对象
    • 根据相同的物料、不同的组装方式产生出具体内容,就是建造者模式的最终意图
    • 即将一个复杂的构建与其表示分离,用同样的构建过程可以创建不同的表示

2、建造者模式:模拟场景

  • 装修套餐选配场景
    • 很多装修公司都会提供一些套餐服务,一般会有:豪华欧式、轻奢田园和现代简约 装修服务套餐。
    • 这些套餐的背后是不同装修材料和设计风格的组合
      • 一级顶、二级顶
      • 多乐士涂料、立邦涂料
      • 圣像地板、德尔地板
      • 马可波罗地砖、东鹏地砖
    • 按照不同的套餐价格,选取不同的品牌进行组合,最终再结合装修面积给出整体报价

3、建造者模式:场景模拟工程

0、工程结构

lino-design-6.0
|——src
	|——main
		|--java
			|--com.lino.design
    			|--ceiling
    				|--LevelOneCeiling.java
    				|--LevelTwoCeiling.java
				|--coat
					|--DuluxCoat.java
    				|--LiBangCoat.java
    			|--floor
					|--DerFloor.java
    				|--ShengXiangFloor.java
    			|--tile
					|--DongPengTile.java
    				|--MarcoPoloTile.java
        		|--Matter.java
  • 在模拟的装修材料工程中,提供了如下类:
    • ceiling(吊顶材料)包:LevelOneCeilingLevelTwoCeiling
    • coat(涂料材料)包:DuluxCoatLiBangCoat
    • floor(地板材料)包:DerFloorShengXiangFloor
    • tile(地砖材料)包:DongPengTileMarcoPoloTile

1、装修材料接口

  • 装修材料接口提供了基本的方法获取信息,以保证所有不同规格和种类的装修材料都可以按照统一标准被获取。
import java.math.BigDecimal;

/**
 * @description: 装修物料
 */
public interface Matter {

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

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

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

    /**
     * 平米报价
     *
     * @return BigDecimal
     */
    BigDecimal price();

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

2、吊顶材料(ceiling)

  • 一级顶
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 吊顶:一级顶
 */
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(260);
    }

    @Override
    public String desc() {
        return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
    }
}
  • 二级顶
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 吊顶:二级顶
 */
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(850);
    }

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

3、涂料材料(coat)

  • 多乐士
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 涂料:多乐士(Dulux)
 */
public class DuluxCoat implements Matter {

    @Override
    public String scene() {
        return "涂料";
    }

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

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

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

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

}
  • 立邦
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 涂料:立邦
 */
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(650);
    }

    @Override
    public String desc() {
        return "立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。";
    }

}

4、地板材料(floor)

  • 德尔
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 地板:德尔(Der)
 */
public class DerFloor implements Matter {

    @Override
    public String scene() {
        return "地板";
    }

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

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

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

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

}
  • 圣像
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 地板:圣象
 */
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(318);
    }

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

5、地砖材料(tile)

  • 东鹏
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 地砖:东鹏瓷砖
 */
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年品牌价值132.35亿元,位列建陶行业榜首。";
    }

}
  • 马克波罗
import com.lino.design.Matter;
import java.math.BigDecimal;

/**
 * @description: 地砖:马可波罗(MARCO POLO)
 */
public class MarcoPoloTile implements Matter {

    @Override
    public String scene() {
        return "地砖";
    }

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

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

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

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

}

4、建造者模式:代码实现

0、工程结构

lino-design-6.0
|——src
	|——main
		|--java
			|--com.lino.builder
    			|--Builder.java
    			|--DecorationPackageMenu.java
    			|--IMenu.java
	|——test
    	|--java
    		|--com.lino.test
    			|--Test.java

设计模式四:创建型-建造者模式

  • 建造者模式代码工程有三个核心类,这三个核心类是建造者模式的具体实现。
    • Builder:建造者类具体的各种组装,都由此类实现。
    • DecorationPackageMenu:是 IMenu 接口的实现类,主要承载建造过程中的填充器,相当于一套承载物料和创建者中间衔接的内容

1、定义装修包接口

  • 装修包接口定义了填充 吊顶、涂料、地板、地砖 各种材料的方法,以及最终提供获取全部明细的方法
import com.lino.design.Matter;

/**
 * @description: 装修包接口
 */
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
     */
    String getDetail();
}

2、实现装修包接口

  • 在装修包的实现中,每一种方法都返回了this对象本身,可以非常方便地用于连续填充各种物料。
  • 在填充时也会根据物料计算相应面积的报价,吊顶和涂料按照面积乘于单价计算
  • 最后,同样提供了统一的获取装修清单的明细方法
import com.lino.design.Matter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 装修包接口实现类
 */
public class DecorationPackageMenu implements IMenu {

    /**
     * 装修清单
     */
    private List<Matter> list = new ArrayList<>();
    /**
     * 装修价格
     */
    private BigDecimal price = BigDecimal.ZERO;

    /**
     * 面积
     */
    private BigDecimal area;
    /**
     * 装修等级;豪华欧式、轻奢田园、现代简约
     */
    private String grade;

    public DecorationPackageMenu() {
    }

    public DecorationPackageMenu(Double area, String grade) {
        this.area = new BigDecimal(area);
        this.grade = grade;
    }

    @Override
    public IMenu appendCeiling(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new BigDecimal("0.2")).multiply(matter.price()));
        return this;
    }

    @Override
    public IMenu appendCoat(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.price()));
        return this;
    }

    @Override
    public IMenu appendFloor(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }

    @Override
    public IMenu appendTile(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }

    @Override
    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();
    }
}

3、建造者类创建

  • 统一的建造方式通过不同物料填充出不同的装修风格:豪华欧式、轻奢田园、现代简约
import com.lino.design.ceiling.LevelOneCeiling;
import com.lino.design.ceiling.LevelTwoCeiling;
import com.lino.design.coat.DuluxCoat;
import com.lino.design.coat.LiBangCoat;
import com.lino.design.floor.ShengXiangFloor;
import com.lino.design.tile.DongPengTile;
import com.lino.design.tile.MarcoPoloTile;

/**
 * @description: 建造者类
 */
public class Builder {

    /**
     * 豪华欧式:吊顶,二级顶,涂料,多乐士,地板,圣象
     *
     * @param area 面积
     * @return IMenu
     */
    public IMenu levelOne(Double area) {
        return new DecorationPackageMenu(area, "豪华欧式")
                .appendCeiling(new LevelTwoCeiling())
                .appendCoat(new DuluxCoat())
                .appendFloor(new ShengXiangFloor());
    }

    /**
     * 豪华欧式:吊顶,二级顶,涂料,立邦,地砖,马可波罗
     *
     * @param area 面积
     * @return IMenu
     */
    public IMenu levelTwo(Double area) {
        return new DecorationPackageMenu(area, "轻奢田园")
                .appendCeiling(new LevelTwoCeiling())
                .appendCoat(new LiBangCoat())
                .appendTile(new MarcoPoloTile());
    }

    /**
     * 豪华欧式:吊顶,二级顶,涂料,立邦,地板,东鹏
     *
     * @param area 面积
     * @return IMenu
     */
    public IMenu levelThree(Double area) {
        return new DecorationPackageMenu(area, "现代简约")
                .appendCeiling(new LevelOneCeiling())
                .appendCoat(new LiBangCoat())
                .appendTile(new DongPengTile());
    }
}

5、单元测试

  • 使用建造者模式分别创建出三种装修套餐的价格,获取详情信息并进行输出
    • levelOnelevelTwolevelThree 对应三种装修风格:豪华欧式、轻奢田园、现代简约
    • 入参是信息是房屋面积,最终获取装修报价单。
import com.lino.builder.Builder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description: 测试类
 */
public class Test {

    @org.junit.Test
    public void testBuilder() throws Exception {
        // 建造者类
        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());

    }
}
  • 测试结果
-------------------------------------------------------
装修清单
套餐等级:豪华欧式
套餐价格:198064.39 元
房屋面积:132.52 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)、第二代、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。


-------------------------------------------------------
装修清单
套餐等级:轻奢田园
套餐价格:119865.00 元
房屋面积:98.25 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:立邦、默认级别、平米价格:650 元。
地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。


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

4、建造者模式:总结

  • 选择建造者模式的条件

    • 当一些基本材料不变,而其组合经常变化时
  • 满足单一职责原则及可复用的技术,建造者独立、易扩展、便于控制细节风险。

  • 缺点:出现特别多的物料及组合时,类的不断扩展也会造成难以维护的问题。

    • 解决:可以把重复的内容抽象到数据库中,按照需要配置,减少大量的重复代码。
上一篇:Java杀死调用cmd命令杀死进程PID


下一篇:/var/run/yum.pid 已被锁定,PID 为 14558 的另一个程序正在运行