倚天屠龙之建造者模式

什么是建造者模式

  • 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
  • 主要解决

主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

  • 何时使用

一些基本部件不会变,而其组合经常变化的时候。
当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

  • 如何解决:将变与不变分离开。
  • 关键代码:
    • 建造者:创建和提供实例
    • 导演:管理建造出来的实例的依赖关系。

简单来说就是:通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程。即一个复杂的对象拆分成多个简单对象进行组装构建

话不多说,上代码

  • 案列描述
    还是拿小傅哥的案例吧,用的是装修,源码地址:itstack-demo-design

    • 装修都需要的物料
      在这里插入图片描述
    • 构建各种套装,每个套装都是由上面的基本物料一个或者多个进行排列组合
  • 普通写法

 public String getMatterList(BigDecimal area, Integer level) {

        List<Matter> list = new ArrayList<Matter>(); // 装修清单
        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();

    }
  • 建造者模式

    ···java
    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()));
    
    
    
  • 普通写法基本上都是复用上面这个代码块 ,那如何优化简写呢?

  • 结构说明
    在这里插入图片描述

  • DecorationPackageMenu类

package org.itstack.demo.design;

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

/**
 * 装修包
 */
public class DecorationPackageMenu {

    // 装修清单(多个基础物料)
    private List<Matter> list = new ArrayList<Matter>();
    // 装修价格
    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 DecorationPackageMenu appendMatter(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new BigDecimal("0.2")).multiply(matter.price()));
        return this;
    }

    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类
package org.itstack.demo.design;

import org.itstack.demo.design.ceiling.LevelOneCeiling;
import org.itstack.demo.design.ceiling.LevelTwoCeiling;
import org.itstack.demo.design.coat.DuluxCoat;
import org.itstack.demo.design.coat.LiBangCoat;
import org.itstack.demo.design.floor.ShengXiangFloor;
import org.itstack.demo.design.tile.DongPengTile;
import org.itstack.demo.design.tile.MarcoPoloTile;

public class Builder {

   public DecorationPackageMenu levelOne(Double area) {
       return new DecorationPackageMenu(area, "豪华欧式")
               .appendMatter(new LevelTwoCeiling())    // 吊顶,二级顶
               .appendMatter(new DuluxCoat())             // 涂料,多乐士
               .appendMatter(new ShengXiangFloor());     // 地板,圣象
   }

   public DecorationPackageMenu levelTwo(Double area){
       return new DecorationPackageMenu(area, "轻奢田园")
               .appendMatter(new LevelTwoCeiling())   // 吊顶,二级顶
               .appendMatter(new LiBangCoat())           // 涂料,立邦
               .appendMatter(new MarcoPoloTile());       // 地砖,马可波罗
   }

   public DecorationPackageMenu levelThree(Double area){
       return new DecorationPackageMenu(area, "现代简约")
               .appendMatter(new LevelOneCeiling())   // 吊顶,二级顶
               .appendMatter(new LiBangCoat())           // 涂料,立邦
               .appendMatter(new DongPengTile());        // 地砖,东鹏
   }

}

使用设计模式后,一眼就能看到有啥物料构成,也利于以后扩展


  • 结尾–广告推广
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值