建造者模式
1. 实例
- 定义一个电脑类,实例化电脑类对象,以及给对象的属性赋值
// 定义一个电脑类,实例化电脑类对象,以及给对象的属性赋值
class Computer{
private String cpu;
private String gpu;
private String memory;
private String hard;
public String getCpu() {
return cpu;
}
public String getGpu() {
return gpu;
}
public String getMemory() {
return memory;
}
public String getHard() {
return hard;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHard(String hard) {
this.hard = hard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", gpu='" + gpu + '\'' +
", memory='" + memory + '\'' +
", hard='" + hard + '\'' +
'}';
}
}
// 客户端 =======================================
public class Test01 {
public static void main(String[] args) {
Computer c = new Computer();
c.setCpu("i9");
c.setGpu("rtx3090");
c.setHard("128T");
c.setMemory("128g");
System.out.println(c);
}
}
上述方法缺点:
1. 客户端程序员,在实例化好对象后需要每个属性赋值,麻烦
2. 违反最少知道原则
建造者模式和工厂模式区别:
1. 工厂模式:实例化一个类对象即可。
2. 建造者模式:实例化对象后需要给对象属性赋值。
针对上面的问题,作者(服务端程序员)专门创建一个ComputerBuilder类,这个类专门负责封装组装电脑的过程。
// 建造者类必须关联相关产品(关联)
class ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
public Computer build(){
computer.setCpu("i9");
computer.setGpu("rtx3090");
computer.setHard("128T");
computer.setMemory("128g");
return computer;
}
}
// 客户端 =======================================
public class Test01 {
public static void main(String[] args) {
ComputerBuilder cb = new ComputerBuilder();
Computer c = cb.build();
System.out.println(c);
}
}
优点: 直接通过ComputerBuilder对象build一个对象即可,不用给属性赋值
缺点: 不能自定义属性值,只有一套属性可用,如果修改,违反开闭原则。
针对上面缺点,作者多增加几个建造者类即可。LowComputerBuilder;MiddleComputerBuilder;MiddleComputerBuilder
优点:可以根据客户需求建造不同产品。
缺点:
1. 不同建造者类的build方法中有些属性可能是不变的,代码可能出现重复。
2. build过程不稳定,如果漏掉一步,代码也不会报错,该属性=null。
针对上面的问题再次修改
1. 创建一个建造者接口,所有建造者类都要实现其接口,把步骤稳定下来。
2. 少实现一个接口中的抽象方法,代码就会报错。
// 定义一个电脑类,实例化电脑类对象,以及给对象的属性赋值
class Computer{
private String cpu;
private String gpu;
private String memory;
private String hard;
public String getCpu() {
return cpu;
}
public String getGpu() {
return gpu;
}
public String getMemory() {
return memory;
}
public String getHard() {
return hard;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHard(String hard) {
this.hard = hard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", gpu='" + gpu + '\'' +
", memory='" + memory + '\'' +
", hard='" + hard + '\'' +
'}';
}
}
interface ComputerBuilder{
void setCpu();
void setGpu();
void setMemory();
void setHard();
Computer build();
}
// 建造者类必须关联相关产品(关联)
class HighComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i9");
}
@Override
public void setGpu() {
computer.setGpu("rtx3090");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
class MiddleComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i7");
}
@Override
public void setGpu() {
computer.setGpu("rtx2090");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
class LowComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i3");
}
@Override
public void setGpu() {
computer.setGpu("gtx1080");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
// 客户端
public class Test01 {
public static void main(String[] args) {
// 低配
ComputerBuilder cb = new LowComputerBuilder();
cb.setCpu();
cb.setGpu();
cb.setHard();
cb.setMemory();
Computer c = cb.build();
System.out.println(c);
// 中配
ComputerBuilder cb2 = new MiddleComputerBuilder();
cb2.setCpu();
cb2.setGpu();
cb2.setHard();
cb2.setMemory();
Computer c2 = cb2.build();
System.out.println(c2);
// 高配
ComputerBuilder cb3 = new HighComputerBuilder();
cb3.setCpu();
cb3.setGpu();
cb3.setHard();
cb3.setMemory();
Computer c3 = cb3.build();
System.out.println(c3);
}
}
上诉方法
优点:
1. 设置属性步骤明确,不会出错
2. 客户端可以扩展,只需要implements ComputerBuilder接口即可
缺点:
1. 客户端还是需要设置每一个属性,违反最少知道原则(迪米特法则) 。
2. 虽然不用知道装电脑的细节(cpu=“i3”)(几个螺丝,什么颜色线),但是需要知道步骤(setCpu())(先装啥再装啥)
2. 建造者模式代码
- 分析上面例子的优缺点,有如下代码
// 定义一个电脑类,实例化电脑类对象,以及给对象的属性赋值
class Computer{
private String cpu;
private String gpu;
private String memory;
private String hard;
public String getCpu() {
return cpu;
}
public String getGpu() {
return gpu;
}
public String getMemory() {
return memory;
}
public String getHard() {
return hard;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHard(String hard) {
this.hard = hard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", gpu='" + gpu + '\'' +
", memory='" + memory + '\'' +
", hard='" + hard + '\'' +
'}';
}
}
interface ComputerBuilder{
void setCpu();
void setGpu();
void setMemory();
void setHard();
Computer build();
}
// 建造者类必须关联相关产品(关联)
class HighComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i9");
}
@Override
public void setGpu() {
computer.setGpu("rtx3090");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
class MiddleComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i7");
}
@Override
public void setGpu() {
computer.setGpu("rtx2090");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
class LowComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer(); // 字段关联
@Override
public void setCpu() {
computer.setCpu("i3");
}
@Override
public void setGpu() {
computer.setGpu("gtx1080");
}
@Override
public void setMemory() {
computer.setMemory("128g");
}
@Override
public void setHard() {
computer.setHard("128T");
}
public Computer build(){
return computer;
}
}
// 指挥者
class Director{
public Computer build(ComputerBuilder cb){
cb.setCpu();
cb.setGpu();
cb.setHard();
cb.setMemory();
return cb.build();
}
}
// =================================================================
// 客户端
// 扩展自定义配置
class SelfComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer();
@Override
public void setCpu() {
computer.setCpu("1");
}
@Override
public void setGpu() {
computer.setGpu("12");
}
@Override
public void setMemory() {
computer.setMemory("123");
}
@Override
public void setHard() {
computer.setHard("1234");
}
@Override
public Computer build() {
return computer;
}
}
public class Test01 {
public static void main(String[] args) {
ComputerBuilder lcb = new LowComputerBuilder();
ComputerBuilder mcb = new MiddleComputerBuilder();
ComputerBuilder hcb = new HighComputerBuilder();
// 自定义
ComputerBuilder scb = new SelfComputerBuilder();
Director director = new Director(); // 指挥者
// 低配
Computer c = director.build(lcb);
System.out.println(c);
// 中配
Computer c2 = director.build(mcb);
System.out.println(c2);
// 高配
Computer c3 = director.build(hcb);
System.out.println(c3);
// 自定义
Computer self = director.build(scb);
System.out.println(self);
}
}
输出结果:
Computer{cpu='i3', gpu='gtx1080', memory='128g', hard='128T'}
Computer{cpu='i7', gpu='rtx2090', memory='128g', hard='128T'}
Computer{cpu='i9', gpu='rtx3090', memory='128g', hard='128T'}
Computer{cpu='1', gpu='12', memory='123', hard='1234'}
上面的代码就是使用了建造者模式。
优点:
1. 创建对象的过程稳定不变,因为有ComputerBuilder接口
2. 设置对象属性封装好了,只需要编写一次(指挥者中build)
3. 客户端可以扩展功能,符合开闭原则
建造者和工厂模式区别:
1. 工厂模式只需要new一个产品即可
2. 建造者模式更加注重的是new 产品之后,对产品赋值属性的过程!
3. UML图
5. 原视频链接
https://www.bilibili.com/video/BV1Qx411o7tN?p=27