Design Pattern [3] —— 建造者模式 Builder
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可创建不同的表示。
使用场景
-
相同的方法,不同的执行顺序。
-
要初始化的对象十分复杂,如参数多且都具有默认值。
例子:
组装电脑的配置
肯德基的套餐配置
Java中的StringBuilder
ps组合使用:工厂模式建造零件,建造者模式创建复杂对象)
优缺点
优点:
-
良好的封装性,可使调用者不必知道产品内部组成的细节。(控制细节风险)
-
建造者独立,容易扩展。
缺点:
- 会产生多余的Builder对象以及Director对象,消耗内存。
我的Github里有源码,可以clone下来自己跑下:https://github.com/Yang2199/Design-Pattern/tree/master/src
例子:
首先创建实体:
import lombok.Data;
@Data
public class Computer{
private String buildA;//内存
private String buildB;//显示屏
private String buildC;//CPU
private String buildD;//键鼠
@Override
public String toString() {
return "Computer{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
创建动作父类(abstract抽象父类):
public abstract class Builder {
//无参构造,均设置好默认值
abstract void buildA();//内存
abstract void buildB();//显示屏
abstract void buildC();//CPU
abstract void buildD();//键鼠
//有参构造,DIY
abstract void buildA(String str);
abstract void buildB(String str);
abstract Computer getComputer();
}
写多个子类,重写父类方法:
public class Worker_Normal extends Builder{
private Computer computer;
public Worker_Normal() {
computer = new Computer();
}
@Override
void buildB() {
computer.setBuildB("1080p显示屏");
System.out.print("1080p显示屏==>");
}
@Override
void buildA() {
computer.setBuildA("1T内存");
System.out.print("1T内存==>");
}
@Override
void buildC() {
computer.setBuildC("i5");
System.out.print("i5==>");
}
@Override
void buildD() {
computer.setBuildD("联想键鼠");
System.out.print("联想键鼠==>");
}
@Override
void buildA(String str) {
computer.setBuildA(str);
}
@Override
void buildB(String str) {
computer.setBuildB(str);
}
@Override
Computer getComputer() {
return computer;
}
}
public class Worker_Good extends Builder{
private Computer computer;
public Worker_Good() {
computer = new Computer();
}
@Override
void buildA() {
computer.setBuildA("2T内存");
}
@Override
void buildB() {
computer.setBuildB("2K显示屏");
}
@Override
void buildC() {
computer.setBuildC("i9");
}
@Override
void buildD() {
computer.setBuildD("罗技键鼠");
}
@Override
void buildA(String str) {
computer.setBuildA(str);
}
@Override
void buildB(String str) {
computer.setBuildB(str);
}
@Override
Computer getComputer() {
return computer;
}
}
写Director,决定顺序和组件个数:
public class Director {
public Computer build(Builder builder){//director的作用很重要,决定具体顺序
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getComputer();
}
}
public class DirectorPRO {
public Computer build(Builder builder){
builder.buildA();
builder.buildA();
builder.buildD();
builder.buildC();
builder.buildB();
return builder.getComputer();
}
}
最后写测试类:
public class Test {
public static void main(String[] args) {
System.out.println("====标配高级电脑====");
Director director = new Director();
Worker_Good worker_good = new Worker_Good();
Computer buildGood = director.build(worker_good); //Alt+Enter自动补全
System.out.println(buildGood.toString() );
System.out.println("====DIY高级电脑====");//设置一些有参构造,可以DIY属性; 无参构造只能是默认属性
Computer buildGoodDIY = director.build(worker_good);
worker_good.buildA("DIY:4T内存");
worker_good.buildB("DIY:4K显示屏");
System.out.println(buildGoodDIY.toString() );
System.out.println("====普通电脑====");
for (int i=0;i<2;i++){
Computer buildNormal = director.build(new Worker_Normal());
System.out.println(buildNormal.toString());
}
System.out.println("====普通电脑PRO====");//这里用了不同的director可使构造的顺序不同(director决定顺序,还有组件数量)
DirectorPRO directorPRO = new DirectorPRO();
for(int i=0;i<1;i++){
Computer buildNormalPro = directorPRO.build(new Worker_Normal());
System.out.println(buildNormalPro);//这里应该是帮助自动toString
System.out.println(buildNormalPro.toString());
}
}
}
程序运行结果:
类图: