建造者模式
需求: 定义一个电脑类,并实例化该电脑类对象,并为该对象的属性赋值
1、平时创建对象并赋值的方式
平时,我们在实例化对象之后必须为该对象的每一个属性赋值,这样对我们来说太麻烦了,而且还违反了迪米特法则。
我们的例子来说,这就相当于我们我们去买电脑,商家把所有配件给我们,叫我们自己组装
class Computer {
private String cpu;
private String gpu;
private String memery;
private String hd;
//....省略get,set方法以及toString方法
}
//以上为客户端,以下为服务端,我们角色为客户(客户端可以随意修改,服务端我们不能操作)
//====================================================================
public class AppTest {
public static void main(String[] args) {
Computer computer = new Computer();
computer.setCpu("");
computer.setGpu("");
computer.setHd("");
computer.setMemery("");
}
这样做的缺点是:
- 客户端程序员在实例化产品对象之后,必须为该对象的每一个属性赋值,这样对于客户端程序员来讲,太麻烦了。
- 违背了迪米特法则
建造者模式与工厂模式的区别:
工厂模式:是直接实例化出一个类的对象即可
建造者模式:实例化类的对象之后,还要给类的属性赋值
2、创建一个专门用于创建电脑的建造类
针对上面的问题,我们专门创建一个ComputerBuilder类,专门用于创建对象
class Computer {
private String cpu;
private String gpu;
private String memery;
private String hd;
//省略get,set,toString方法
}
//低配电脑
class LowComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("");
computer.setGpu("");
computer.setHd("");
computer.setMemery("");
return computer;
}
}
//中配电脑
class MiddleComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("");
computer.setGpu("");
computer.setHd("");
computer.setMemery("");
return computer;
}
}
//高配电脑
class HeightComputerBuilder {
private Computer computer = new Computer();
public Computer build(){
computer.setCpu("");
computer.setGpu("");
computer.setHd("");
computer.setMemery("");
return computer;
}
}
//====================================================================
public class AppTest {
public static void main(String[] args) {
//购买低配电脑
LowComputerBuilder c1 = new LowComputerBuilder();
Computer build = c1.build();
//购买中配电脑
MiddleComputerBuilder c2 = new MiddleComputerBuilder();
Computer build1 = c2.build();
//购买高配电脑
HeightComputerBuilder c3 = new HeightComputerBuilder();
Computer build2 = c3.build();
}
}
这样设计仍然不属于建造者模式。
优点:
- 可以根据不同的需求,使用不同的建造着来进行生产
缺点:
- 我们发现不同的建造者中的代码,在重复,既然代码中出现了重复的代码,那就有了“坏味道”
- 建造的过程不稳定,如果在建造者在建造的过程中,如果漏掉了某一部(比如创建的过程中中cup,gpu,hq都装了,但是没有装memary),编译器也不会报错。(举个例子来说,就类似于KFC的某一家分店,在制作汉堡包的过程中突然少了某一个步骤,出来的汉堡包的味道就变了,因为没有标准)
3、创建规范接口,规范创建的类
针对2中产生的问题,修改代码如下:
创建一个建造者接口,吧制作的具体流程稳定下来,我们让建造者类去实现建造者接口,接口中的方法步骤类都必须进行实现,少实现一个抽象方法就会报错。
class Computer {
private String cpu;
private String gpu;
private String memery;
private String hd;
// ..... 此处省略get,set方法
}
interface ComputerBuilder {
void setCpu();
void setGpu();
void setHd();
void setMemary();
Computer build();
}
//低配
class LowComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("1");
}
@Override
public void setGpu() {
c.setGpu("2");
}
@Override
public void setHd() {
c.setHd("3");
}
@Override
public void setMemary() {
c.setMemery("4");
}
@Override
public Computer build() {
return c;
}
}
//中配
class MiddleComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("3");
}
@Override
public void setGpu() {
c.setGpu("3");
}
@Override
public void setHd() {
c.setHd("3");
}
@Override
public void setMemary() {
c.setMemery("3");
}
@Override
public Computer build() {
return c;
}
}
//高配
class HeightComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("4");
}
@Override
public void setGpu() {
c.setGpu("4");
}
@Override
public void setHd() {
c.setHd("4");
}
@Override
public void setMemary() {
c.setMemery("4");
}
@Override
public Computer build() {
return c;
}
}
//====================================================================
public class AppTest {
public static void main(String[] args) {
LowComputer c1 = new LowComputer();
MiddleComputer c2 = new MiddleComputer();
HeightComputer c3 = new HeightComputer();
//低配电脑
c1.setCpu();
c1.setGpu();
c1.setHd();
c1.setMemary();
Computer build = c1.build();
//中配电脑
c2.setCpu();
c2.setGpu();
c2.setHd();
c2.setMemary();
Computer build1 = c2.build();
//高配电脑
c3.setCpu();
c3.setGpu();
c3.setHd();
c3.setMemary();
Computer build2 = c3.build();
System.out.println(build);
System.out.println(build1);
System.out.println(build2);
}
}
这个还不是构造者模式,
优点:
- 建造类中建造过程使稳定的,不会漏掉某一步,这样客户端想要扩展建造者时,也不会漏掉某一步。
缺点:
- 代码任然重复
- 现在又变成了客户端自己来进行配置电脑,又违反了迪米特法则(着相当于你去赛格配置电脑,虽然不用你亲自组装电脑,但是你必须指挥那个组装电脑的人,该装什么该装什么),如果你在指挥的过程中如果漏了哪一步,依旧会使该电脑缺少一些部件或者功能。
4、创建一个指挥者,用于创建电脑(这就是建造者模式)
针对上面的的问题,我们创建一个指挥者Director,用于指挥商品的创建
class Computer {
private String cpu;
private String gpu;
private String memery;
private String hd;
// .... 此处省略get set方法
}
interface ComputerBuilder {
void setCpu();
void setGpu();
void setHd();
void setMemary();
Computer build();
}
//低配
class LowComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("1");
}
@Override
public void setGpu() {
c.setGpu("2");
}
@Override
public void setHd() {
c.setHd("3");
}
@Override
public void setMemary() {
c.setMemery("4");
}
@Override
public Computer build() {
return c;
}
}
//中配
class MiddleComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("3");
}
@Override
public void setGpu() {
c.setGpu("3");
}
@Override
public void setHd() {
c.setHd("3");
}
@Override
public void setMemary() {
c.setMemery("3");
}
@Override
public Computer build() {
return c;
}
}
//高配
class HeightComputer implements ComputerBuilder{
private Computer c = new Computer();
@Override
public void setCpu() {
c.setCpu("4");
}
@Override
public void setGpu() {
c.setGpu("4");
}
@Override
public void setHd() {
c.setHd("4");
}
@Override
public void setMemary() {
c.setMemery("4");
}
@Override
public Computer build() {
return c;
}
}
//指挥者
class Director {
public Computer build(ComputerBuilder builder){
builder.setCpu();
builder.setGpu();
builder.setMemary();
builder.setHd();
return builder.build();
}
}
//====================================================================
public class AppTest {
public static void main(String[] args) {
Director director = new Director();
LowComputer c1 = new LowComputer();
MiddleComputer c2 = new MiddleComputer();
HeightComputer c3 = new HeightComputer();
//低配电脑
Computer build = director.build(c1);
//中配电脑
Computer build1 = director.build(c2);
//高配电脑
Computer build2 = director.build(c3);
System.out.println(build);
System.out.println(build1);
System.out.println(build2);
}
}
这就是建造者模式
优点:
- 创建过程是稳定不变的(因为有ComputerBuilder接口来稳定过程)
- 创建过程只写了一次,没有重复的代码(由Director指挥完成)
以上内容为课后总结,如有侵权,请告知本人!