建造者模式(Builder Pattern)
概念
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的,相当于聚合其他的类,完成最终可供选择的产品;这里可以抽象为表示与构建过程进行分离,客户端只需关注表示出来的东西;
简介
作用及优势
- 将复杂的构建过程与最终需要表示的东西分开来
- 根据表示层的需求,可以利用一些不变的东西去随意组装
- 解耦,把复杂对象的构建过程,拆分成具有独立功能的类(类似零件 的存在),然后再进行组装
- 灵活性、重用性高,根据需求的变更,可以给出不同的组合;
不足之处
- 这一类元件大部分只能组装成一个系列的产品;
- 零件 越多,证明需要创建的类越多,这样之前的组装好的建造者,可能也需要随之改变;
应用实例
- 建造者模式的经典案例就是lombok的@Builder注解,提供建造者模式去构建自己最后想要的对象,这里没有用的小伙伴可以去试试;
- 通过积木可以组装成各类房子
- java的StringBuilder
代码
案例描述
有个电脑店(ComputerBuilder),他有很多材料可以使用,最后需要给出几套方案:有高配的、中配的、低配的;顾客想买的话就直接提走就行了,不需要自己组装电脑(当然向我们程序员肯定是要自己体验组装的乐趣了😁),这大概就是建造者模式的概念;
工程目录
项目类图
具体实现
材料抽象类(Material) :提供了一些属性用于子类复用;
/**
* @author chengxing.wu
* @date 2021/6/17
*/
public abstract class Material {
/**
* 品牌
*/
protected String brand;
/**
* 价格
*/
protected BigDecimal price;
/**
* 大小
*/
protected String size;
/**
* 描述
*/
protected String desc;
protected Material(String brand, BigDecimal price, String size, String desc) {
this.brand = brand;
this.price = price;
this.size = size;
this.desc = desc;
}
}
产品抽象类 :CPU、Memory、Disk
public class CPU extends Material {
protected CPU(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
}
-----------------------------------
public class Memory extends Material {
protected Memory(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
}
------------------------------------
public class Disk extends Material {
protected Disk(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
}
cpu具体实现(intel) :
public class Intel extends CPU {
protected Intel(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
protected Intel(String brand, BigDecimal price, String size) {
this(brand, price, size, "Intel-我就是喜欢挤牙膏...");
}
static class IntelFactory {
public static CPU create(String level) {
if (BuilderConstant.LEVEL_HIGH.equals(level)) {
return getHighIntel();
} else if (BuilderConstant.LEVEL_MID.equals(level)) {
return getMidIntel();
} else if (BuilderConstant.LEVEL_LOW.equals(level)) {
return getLowIntel();
} else {
return null;
}
}
public static Intel getHighIntel() {
return new Intel("Intel-i9750H", new BigDecimal("2000"), "标压");
}
public static Intel getMidIntel() {
return new Intel("Intel-i8750H", new BigDecimal("1500"), "标压");
}
public static Intel getLowIntel() {
return new Intel("Intel-U5500", new BigDecimal("800"), "低压");
}
}
}
tips: 这里面应该将每一种规格的Intel都抽离出来的,但是过于臃肿,所以这里选择使用工厂方法去实现多规格产品;
Memory的具体实现(Samsung) :跟cpu的实现原理一样;
public class Samsung extends Memory {
protected Samsung(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
protected Samsung(String brand, BigDecimal price, String size) {
this(brand, price, size, "三星-性能好,我不会爆炸的...");
}
/**
* 这些类可以抽出来 结合抽象工厂来实现 分为不同的 类型模板,这里用的是 工厂方法
*/
static class SamsungFactory {
public static Memory create(String level) {
if (BuilderConstant.LEVEL_HIGH.equals(level)) {
return getHighIntel();
} else if (BuilderConstant.LEVEL_MID.equals(level)) {
return getMidIntel();
} else if (BuilderConstant.LEVEL_LOW.equals(level)) {
return getLowIntel();
} else {
return null;
}
}
public static Samsung getHighIntel() {
return new Samsung("Samsung-DDR4-3200", new BigDecimal("1200"), "32GB");
}
public static Samsung getMidIntel() {
return new Samsung("Samsung-DDR4-2666", new BigDecimal("1100"), "32GB");
}
public static Samsung getLowIntel() {
return new Samsung("Samsung-DDR4-2666", new BigDecimal("600"), "16GB");
}
}
}
Disk的的具体实现(Kingston) :跟cpu的实现原理一样;
public class Kingston extends Disk {
protected Kingston(String brand, BigDecimal price, String size, String desc) {
super(brand, price, size, desc);
}
protected Kingston(String brand, BigDecimal price, String size) {
this(brand, price, size, "金士顿-性能好,就是稍微贵点...");
}
static class KingstonFactory {
public static Disk create(String level) {
if (BuilderConstant.LEVEL_HIGH.equals(level)) {
return getHighIntel();
} else if (BuilderConstant.LEVEL_MID.equals(level)) {
return getMidIntel();
} else if (BuilderConstant.LEVEL_LOW.equals(level)) {
return getLowIntel();
} else {
return null;
}
}
public static Kingston getHighIntel() {
return new Kingston("Kingston-m.2-a400", new BigDecimal("700"), "1024GB");
}
public static Kingston getMidIntel() {
return new Kingston("Kingston-m.2-sata总线", new BigDecimal("380"), "512GB");
}
public static Kingston getLowIntel() {
return new Kingston("Kingston-sata3.0", new BigDecimal("300"), "512GB");
}
}
}
电脑构建工厂(ComputerBuilder)
public class ComputerBuilder {
public static void builder(String level) {
if (BuilderConstant.LEVEL_HIGH.equals(level)) {
highBuilder();
} else if (BuilderConstant.LEVEL_MID.equals(level)) {
midBuilder();
} else if (BuilderConstant.LEVEL_LOW.equals(level)) {
lowBuilder();
}
}
/**
* 这些builder可以作为子建造者,以集成的方式做,类似于工厂,之后想增加新的构建的时候,只要新加类就行,不会对代码造成侵入
*
* @return
*/
private static void highBuilder() {
CPU cpu = Intel.IntelFactory.create(BuilderConstant.LEVEL_HIGH);
Disk disk = Kingston.KingstonFactory.create(BuilderConstant.LEVEL_HIGH);
Memory memory = Samsung.SamsungFactory.create(BuilderConstant.LEVEL_HIGH);
printLevel(cpu, disk, memory, "high");
}
private static void midBuilder() {
CPU cpu = Intel.IntelFactory.create(BuilderConstant.LEVEL_MID);
Disk disk = Kingston.KingstonFactory.create(BuilderConstant.LEVEL_MID);
Memory memory = Samsung.SamsungFactory.create(BuilderConstant.LEVEL_MID);
printLevel(cpu, disk, memory, "mid");
}
private static void lowBuilder() {
CPU cpu = Intel.IntelFactory.create(BuilderConstant.LEVEL_LOW);
Disk disk = Kingston.KingstonFactory.create(BuilderConstant.LEVEL_LOW);
Memory memory = Samsung.SamsungFactory.create(BuilderConstant.LEVEL_LOW);
printLevel(cpu, disk, memory, "low");
}
private static void printLevel(CPU cpu, Disk disk, Memory memory, String type) {
BigDecimal decimal = Objects.requireNonNull(cpu)
.price.add(Objects.requireNonNull(disk)
.price.add(Objects.requireNonNull(memory).price));
System.out.println("========== " + type.toUpperCase() + " ===========");
System.out.println("========== CPU:" + cpu.brand + "/" + cpu.brand + "/"
+ cpu.size + "/" + cpu.desc + ", " + "价格:===> " + cpu.price + " ===========");
System.out.println("========== DISK:" + disk.brand + "/" + disk.brand + "/"
+ disk.size + "/" + disk.desc + ", " + "价格:===> " + disk.price + " ===========");
System.out.println("========== MEMORY:" + memory.brand + "/" + memory.brand + "/"
+ memory.size + "/" + memory.desc + ", " + "价格:===> " + memory.price + " ===========");
System.out.println(type + "--价格(总价):===> " + decimal);
}
}
这里有点类似用工厂去管理各种建造者(highBuilder、midBuilder、lowBuilder);每个构建者都是由零件组装而成;然后就交由工厂管理,大概就是这样的设计;
常量类: BuilderConstant
public class BuilderConstant {
/**
* 低配
*/
public static final String LEVEL_LOW = "low";
/**
* 中配
*/
public static final String LEVEL_MID = "mid";
/**
* 高配
*/
public static final String LEVEL_HIGH = "high";
}
测试
public class BuilderTest {
public static void main(String[] args) {
ComputerBuilder.builder(BuilderConstant.LEVEL_LOW);
ComputerBuilder.builder(BuilderConstant.LEVEL_MID);
ComputerBuilder.builder(BuilderConstant.LEVEL_HIGH);
}
}
结果: 可以看出这里组合成了三种价位,除此之外,我们可以根据用户提出来的需求再次组装,而不会影响之前的代码逻辑;且这些产品信息也是可以复用的;
========== LOW ===========
========== CPU:Intel-U5500/Intel-U5500/低压/Intel-我就是喜欢挤牙膏..., 价格:===> 800 ===========
========== DISK:Kingston-sata3.0/Kingston-sata3.0/512GB/金士顿-性能好,就是稍微贵点..., 价格:===> 300 ===========
========== MEMORY:Samsung-DDR4-2666/Samsung-DDR4-2666/16GB/三星-性能好,我不会爆炸的..., 价格:===> 600 ===========
low--价格(总价):===> 1700
========== MID ===========
========== CPU:Intel-i8750H/Intel-i8750H/标压/Intel-我就是喜欢挤牙膏..., 价格:===> 1500 ===========
========== DISK:Kingston-m.2-sata总线/Kingston-m.2-sata总线/512GB/金士顿-性能好,就是稍微贵点..., 价格:===> 380 ===========
========== MEMORY:Samsung-DDR4-2666/Samsung-DDR4-2666/32GB/三星-性能好,我不会爆炸的..., 价格:===> 1100 ===========
mid--价格(总价):===> 2980
========== HIGH ===========
========== CPU:Intel-i9750H/Intel-i9750H/标压/Intel-我就是喜欢挤牙膏..., 价格:===> 2000 ===========
========== DISK:Kingston-m.2-a400/Kingston-m.2-a400/1024GB/金士顿-性能好,就是稍微贵点..., 价格:===> 700 ===========
========== MEMORY:Samsung-DDR4-3200/Samsung-DDR4-3200/32GB/三星-性能好,我不会爆炸的..., 价格:===> 1200 ===========
high--价格(总价):===> 3900