设计模式-建造者模式

什么是建造者模式?
在这里插入图片描述

建造者模式是通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程。

简单模拟场景:

装修公司的套餐服务,豪华、简约风格。比如对于吊顶和地板,有一级二级吊顶,一级二级地板等。按不同的套餐价格选取不同的组合。

物料接口:

public interface Matter {

    String scene(); // 场景:吊顶、地板
    
    String brand(); // 品牌
    
    String model(); // 型号
    
    BigDecimal price(); // 价格
    
    String desc(); // 描述
}

  • 物料接口提供了基本信息。

吊顶:

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";
    }
}
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(500);
    }

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

地板:

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

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

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

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

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

这里我们会把构建的过程交给创建者类,而创建者通过使用我们的构建工具包,去构建出不同的装修套餐

  • Builder,建造者类具体的各种组装由此类实现。
  • DecorationPackageMenu,是IMenu接口的实现类,主要承载构造过程中的填充器。相当于这是一套承载物料和创建者中间衔接的内容。

定义装修包接口:

public interface IMenu {
    
    IMenu appendCeiling(Matter matter); // 吊顶
    
    IMenu appendFloor(Matter matter); // 地板
    
    String getDetail(); // 明细
}

接口中定义了田中各项物料的方法;吊顶、地板,以及最终提供获取全部明细的方法。

装修包实现:

public class DecorationPackageMenu implements IMenu{

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

    private BigDecimal area; // 面积
    private String grade; // 装修等级

    private DecorationPackageMenu() {}

    public DecorationPackageMenu(BigDecimal area, String grade) {
        this.area = 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 appendFloor(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();
    }
}
  • 装修包的实现中每一个方法都返回了 this,也就可以非常方便的用于连续填充各项物料。

建造者方法:

public class Builder {

    public IMenu levelOne(BigDecimal area) {
        return new DecorationPackageMenu(area, "豪华")
                .appendCeiling(new LevelOneCeiling())
                .appendFloor(new ShengXiangFloor());
    }
    
    public IMenu levelTwo(BigDecimal area) {
        return new DecorationPackageMenu(area, "简约")
                .appendCeiling(new LevelTwoCeiling())
                .appendFloor(new DerFloor());
    }
}

建造者的使用就非常容易,通过不同的物料填充不同的装修风格。

测试:

public class AppTest {
    @Test
    public void test() {
        Builder builder = new Builder();
        // 豪华
        IMenu levelOne = builder.levelOne(new BigDecimal(500));
        System.out.println(levelOne.getDetail());
        // 简约
        IMenu levelTwo = builder.levelTwo(new BigDecimal(100));
        System.out.println(levelTwo.getDetail());
    }
}

这样方便进行业务扩展。

总结:

  • 什么时候选择建造者模式?当一些基本物料不会变,而其组合经常变化的时候
  • 此设计模式满足了单一职责原则以及可复用的技术、建造者独立、易扩展、便于控制细节风险。但同时当出现特别多的物料以及很多的组合后,类的不断扩展也会造成难以维护的问题。但这种设计结构模型可以把重复的内容抽象到数据库中,按照需要配置。这样就可以减少代码中大量的重复。

参考来源–https://bugstack.cn/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值