先来看一段代码
@Setter
@Getter
@ToString
class Computer {
private String cpu;
private String gpu;
private String memory;
private String hd;
}
public class AppTest {
public static void main(String[] args) {
Computer c = new Computer();
c.setCpu("i10 9600");
c.setGpu("2080super");
c.setMemory("16g");
c.setHd("1T机械");
System.out.println(c);
}
}
Computer(cpu=i10 9600, gpu=2080super, memory=16g, hd=1T机械)
当我还是个小白的时候,我对电脑的了解并不多,只知道cpu和显卡(gpu),到大学时,我买了我的第一台电脑,我是根据cpu和显卡来买的,其他的我根本没有关注到,但是也有人是根据内存来买的,还有的人对电脑一窍不通。现在回看上面的代码,如果我不设置computer的这四个属性,那么输出时的电脑就不是完整的。这显然是不符合实际的。所以说,当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。可以把建造者认为是电脑城的师傅(电脑城水很深,你把握不住),他会亲自给你推荐,而不必你自己去选,你只需把你想要的告诉他,他来帮你完成其他部分的选择。
改进1
通过上面的分析,可以先进行改进
①创建电脑城的老师傅
/**
* 电脑建造者类,必须关联电脑产品
*/
class ComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("i7 8750HK");
computer.setGpu("rtx2080ti");
computer.setMemory("32g");
computer.setHd("500g固态+2T机械");
return computer;
}
}
②修改main方法,让老师傅帮你创建电脑
public class AppTest {
public static void main(String[] args) {
ComputerBuilder computerBuilder = new ComputerBuilder();
Computer c = computerBuilder.build();
System.out.println(c);
}
}
Computer(cpu=i7 8750HK, gpu=rtx2080ti, memory=32g, hd=500g固态+2T机械)
目前(还不是建造者模式)
优点:1、电脑小白需要一个电脑时,可以直接向老师傅要即可。老师傅直接封装了创建电脑的"复杂"过程。
缺点:1、封装的太狠,无论客户的需求是什么,都是采用最高配置。不管你拿电脑办公还是开发都给你配置最贵的电脑。
改进2
针对以上问题,我们需要创建不同的建造者,来分别生产不同配置的产品
①划分不同的电脑配置建造者
class AdvanceComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("i7 8750HK");
computer.setGpu("rtx2080ti");
computer.setMemory("32g");
computer.setHd("500g固态+2T机械");
return computer;
}
}
class MiddleComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("i5 8750HK");
computer.setGpu("gtx1060ti");
computer.setMemory("16g");
computer.setHd("256g固态+1T机械");
return computer;
}
}
class LowComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("i5 7500u");
computer.setGpu("gtx940mx");
computer.setMemory("8g");
computer.setHd("1T机械");
return computer;
}
}
②修改main方法,针对不同的需求生产不同的电脑
public class AppTest {
public static void main(String[] args) {
AdvanceComputerBuilder acb = new AdvanceComputerBuilder();
MiddleComputerBuilder mcb = new MiddleComputerBuilder();
LowComputerBuilder lcb = new LowComputerBuilder();
// 玩游戏
Computer c1 = acb.build();
System.out.println(c1);
// 开发
Computer c2 = mcb.build();
System.out.println(c2);
// 娱乐办公
Computer c3 = lcb.build();
System.out.println(c3);
}
}
Computer(cpu=i7 8750HK, gpu=rtx2080ti, memory=32g, hd=500g固态+2T机械)
Computer(cpu=i5 8750HK, gpu=gtx1060ti, memory=16g, hd=256g固态+1T机械)
Computer(cpu=i5 7500u, gpu=gtx940mx, memory=8g, hd=1T机械)
目前(不是建造者模式)
优点:1、可以根据客户端的不同请求,使用不同的建造者来生产产品
缺点:2、建造的过程不稳定,如果某个建造者创建产品的过程中,漏掉了一步,编译器也不会报错!
改进3
针对上面的问题,修改代码如下:
创建一个建造者接口,把制作产品的具体步骤稳定下来!
①创建接口
interface ComputerBuilder{
void setCpu();
void setGpu();
void setHd();
void setMemory();
Computer build();
}
②使其他3个不同等级的电脑类继承这个接口(此处只放一个的代码)
class AdvanceComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer();
@Override
public void setCpu() {
computer.setCpu("i7 8750HK");
}
@Override
public void setGpu() {
computer.setGpu("rtx2080ti");
}
@Override
public void setHd() {
computer.setMemory("32g");
}
@Override
public void setMemory() {
computer.setHd("500g固态+2T机械");
}
@Override
public Computer build(){
return computer;
}
}
③修改main方法
public class AppTest {
public static void main(String[] args) {
AdvanceComputerBuilder acb = new AdvanceComputerBuilder();
// 玩游戏
acb.setCpu();
acb.setGpu();
acb.setHd();
acb.setMemory();
Computer c1 = acb.build();
System.out.println(c1);
}
}
Computer(cpu=i7 8750HK, gpu=rtx2080ti, memory=32g, hd=500g固态+2T机械)
目前(不是建造者模式)
优点:建造者类中的建造过程是稳定的,不会漏掉某一步!!这样当客户端想拓展建造者时,也不会漏掉某一步。
缺点:1、代码仍然有重复 2、现在又变成了用户自己配置电脑,虽然用户不用知道具体装配的零件,但是得知道电脑架构。如:小白知道电脑需要硬盘,但是不知道海盗船硬盘,只是让老师傅装下硬盘,小白就相当于指挥者,指导老师傅现在该装什么,下一步该装什么。
改进4
根据上面的问题,我们知道用户还得充当指挥者的角色,如果在建造者中创建指挥者,那么指挥跟建造一体化,用户也就不用管那么多了。这便是建造者模式。
①添加指挥者
class Derictor {
public Computer build(ComputerBuilder cb){
cb.setCpu();
cb.setGpu();
cb.setHd();
cb.setMemory();
return cb.build();
}
}
②修改main方法(此时用户直接调用指挥者进行建造即可)
public class AppTest {
public static void main(String[] args) {
AdvanceComputerBuilder acb = new AdvanceComputerBuilder();
MiddleComputerBuilder mcb = new MiddleComputerBuilder();
LowComputerBuilder lcb = new LowComputerBuilder();
Derictor derictor = new Derictor();
// 玩游戏
Computer c1 = derictor.build(acb);
System.out.println(c1);
// 开发
Computer c2 = derictor.build(mcb);
System.out.println(c2);
// 娱乐办公
Computer c3 = derictor.build(lcb);
System.out.println(c3);
}
}
Computer(cpu=i7 8750HK, gpu=rtx2080ti, memory=32g, hd=500g固态+2T机械)
Computer(cpu=i5 8750HK, gpu=gtx1060ti, memory=16g, hd=256g固态+1T机械)
Computer(cpu=i5 7500u, gpu=gtx940mx, memory=8g, hd=1T机械)
类图展示

目前(建造者模式)
优点:
1、创建对象的过程是稳定不变的(因为有ComputerBuilder接口来稳定过程)
2、创建对象的过程只写了一次,没有重复的代码(指挥者完成)
3、当需要拓展建造者的时候,不用修改之前的代码,这符合了开闭原则
比如:现在需要添加一个中高配电脑,我们添加如下代码即可
class MiddleHighComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void setCpu() {
computer.setCpu("i7 7500u");
}
@Override
public void setGpu() {
computer.setGpu("gtx1080mx");
}
@Override
public void setHd() {
computer.setHd("500G固态+1T机械");
}
@Override
public void setMemory() {
computer.setMemory("16g");
}
@Override
public Computer build(){
return computer;
}
}
创建中高配电脑
public class AppTest {
public static void main(String[] args) {
AdvanceComputerBuilder acb = new AdvanceComputerBuilder();
MiddleComputerBuilder mcb = new MiddleComputerBuilder();
LowComputerBuilder lcb = new LowComputerBuilder();
MiddleHighComputerBuilder mhcb = new MiddleHighComputerBuilder();
Derictor derictor = new Derictor();
//中高配电脑
Computer c0 = derictor.build(mhcb);
System.out.println(c0);
}
}
Computer(cpu=i7 7500u, gpu=gtx1080mx, memory=16g, hd=500G固态+1T机械)
建造者模式和工厂模式的区别
工厂模式:直接实例化一个类的对象即可
建造者模式:实例化出类的对象之后,还要给该对象的属性赋值
网友评论