有一个需求,要配置一台电脑,电脑属性包括cpu,gpu,memory,hd。
传统的代码如下:
Computer类
public class Computer {
private String cpu;
private String gpu;
private String memory;
private String hd;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getGpu() {
return gpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getHd() {
return hd;
}
public void setHd(String hd) {
this.hd = hd;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", gpu='" + gpu + '\'' +
", memory='" + memory + '\'' +
", hd='" + hd + '\'' +
'}';
}
}
测试类
public class AppTest {
public static void main(String[] args) {
Computer computer=new Computer();
computer.setCpu("i9-9900");
computer.setGpu("2080ti");
computer.setMemory("4G");
computer.setHd("500g+500G固态");
System.out.println(computer);
}
}
这样写存在的问题有哪些?
- 客端程序员需要自己手动初始各种属性。这样做不好,违反了迪米特法则(相当于配电脑,用户拿了一堆配件回来,要自己组装)
为了解决上述的问题(用户知道的太多了),重构代码如下(把设置电脑属性的代码封装起来)
public class ComputerBulider {
private Computer computer=new Computer();
public Computer bulid(){
computer.setCpu("i9-9900");
computer.setGpu("2080ti");
computer.setMemory("4G");
computer.setHd("500g+500G固态");
return computer;
}
}
public class AppTest {
public static void main(String[] args) {
ComputerBulider bulider=new ComputerBulider();
//学习用的电脑
Computer computer1=bulider.bulid();
System.out.println(computer1);
//看电影用的电脑
Computer computer2=bulider.bulid();
System.out.println(computer2);
//玩游戏用的电脑
Computer computer3=bulider.bulid();
System.out.println(computer3);
}
}
分析一下重构之后的代码:
- 这样做虽然解决了客户端不用去设置属性的问题 *
缺点:封装的太狠,不灵活,不能更加客户具体的需求来指定对象,例如学习,看电影,玩游戏只能创建同一种配置的电脑,这显然不符合需求。
针对于上述的问题,继续进行重构:
public class HighComputerBulider {
private Computer computer=new Computer();
public Computer bulid(){
computer.setCpu("i9-9900");
computer.setGpu("2080ti");
computer.setMemory("4G");
computer.setHd("1T+500G固态");
return computer;
}
}
class MiddleComputerBulider {
private Computer computer=new Computer();
public Computer bulid(){
computer.setCpu("i7-7700");
computer.setGpu("1060 6g");
computer.setMemory("4G");
computer.setHd("500G+500G固态");
return computer;
}
}
class LowComputerBulider {
private Computer computer=new Computer();
public Computer bulid(){
computer.setCpu("i5-5500");
computer.setGpu("1050");
computer.setMemory("4G");
computer.setHd("1T");
return computer;
}
}
public class AppTest {
public static void main(String[] args) {
HighComputerBulider highComputerBulider=new HighComputerBulider();
//玩游戏用的电脑
Computer computer1=highComputerBulider.bulid();
System.out.println(computer1);
//学习用的
MiddleComputerBulider middleComputerBulider=new MiddleComputerBulider();
Computer computer2=middleComputerBulider.bulid();
System.out.println(computer2);
//看电影用的
LowComputerBulider lowComputerBulider=new LowComputerBulider();
Computer computer3=lowComputerBulider.bulid();
System.out.println(computer3);
}
}
分析一下上述重构的代码:
- 这样做虽然解决了不够灵活的问题,根据不同的需求建造不同的电脑 *
- 缺点:无论是高配,中配,低配,构建过程是一样的,出现了重复的代码,就有了坏味道。 万一装机人员手滑了,忘记装了某个东西,也没有错误提示。
针对上述问题再次进行重构
- 1.创建指挥者,让指挥者把装机过程封装起来,稳定下来 *
- 2.客户端只调用指挥者即可
建造者类
interface ComputerBulider{
void setCpu();
void setGpu();
void setMemory();
void setHd();
Computer build();
}
public class HighComputerBulider implements ComputerBulider {
private Computer computer=new Computer();
@Override
public void setCpu() {
computer.setCpu("i9-9900");
}
@Override
public void setGpu() {
computer.setGpu("2060ti");
}
@Override
public void setMemory() {
computer.setMemory("16G");
}
@Override
public void setHd() {
computer.setHd("1T+500G固态");
}
@Override
public Computer build() {
return computer;
}
}
class MiddleComputerBulider implements ComputerBulider{
private Computer computer=new Computer();
@Override
public void setCpu() {
computer.setCpu("i7-7700");
}
@Override
public void setGpu() {
computer.setGpu("1060 6g");
}
@Override
public void setMemory() {
computer.setMemory("8G");
}
@Override
public void setHd() {
computer.setHd("500G+500G固态");
}
@Override
public Computer build() {
return computer;
}
}
class LowComputerBulider implements ComputerBulider {
private Computer computer=new Computer();
@Override
public void setCpu() {
computer.setCpu("i5-5500");
}
@Override
public void setGpu() {
computer.setGpu("1050");
}
@Override
public void setMemory() {
computer.setMemory("4G");
}
@Override
public void setHd() {
computer.setHd("1T");
}
@Override
public Computer build() {
return computer;
}
}
指挥者类
public class Director {
private ComputerBulider bulider;
public void setBulider(ComputerBulider bulider) {
this.bulider = bulider;
}
public Computer build(){
bulider.setCpu();
bulider.setGpu();
bulider.setMemory();
bulider.setHd();
return bulider.build();
}
}
测试类
public class AppTest {
public static void main(String[] args) {
Director director=new Director();
HighComputerBulider highComputerBulider=new HighComputerBulider();
MiddleComputerBulider middleComputerBulider=new MiddleComputerBulider();
LowComputerBulider lowComputerBulider=new LowComputerBulider();
//玩游戏用的电脑
director.setBulider(highComputerBulider);
Computer computer1=director.build();
System.out.println(computer1);
//学习用的
director.setBulider(middleComputerBulider);
Computer computer2=director.build();
System.out.println(computer2);
//看电影用的
director.setBulider(lowComputerBulider);
Computer computer3=director.build();
System.out.println(computer3);
}
}
这就是完整的建造者模式了,这样设计的优点有:
- 1.客户端不知道安装过程,安装过程被封装在指挥者中
- 2.安装过程是稳定的,不同配置的电脑安装过程是一样的,配置过程在指挥者中稳定下来。
- 3.不同的配置电脑步骤是一样的,提高代码了重用性。
最后给大家看一下建造者模式的UML类图:

对比前面提到的抽象工厂设计模式:
抽象工厂设计模式介绍
两者的区别有:
- 1.抽象工厂模式不会关心构建过程,只关心什么产品由什么工厂生产即可
- 2.建造者模式是一步一步的按步骤所有方法加到一起才能生成一个对象。
856

被折叠的 条评论
为什么被折叠?



