老规矩,先看定义
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示
又是一脸懵逼对吧?我也是,但是这些都可以放在后边解决,现在需要解决的是,如何使用。我们不用说每次都要先搞清楚概念,应该是先学代码,至于其中的道理和那些晦涩难懂的术语,可以先放下,时间到了,自然就懂了,无论学什么知识都是如此。
那么,构建者模式的使用场景是什么?
当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。
这个意思比较简单,意思就是一个类有可选参数而且个数多的时间,可以使用这个模式。
我们来通过例子说明吧。
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:09:33
* 【Function】 目标类
*/
public class Computer {
private String cpu;//必须
private String ram;//必须
private int usbCount;//可选
private String keyboard;//可选
private String display;//可选
public Computer(String cpu, String ram) {
this.cpu = cpu;
this.ram = ram;
}
public void setUsbCount(int usbCount) {
this.usbCount = usbCount;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public void setDisplay(String display) {
this.display = display;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", usbCount=" + usbCount +
", keyboard='" + keyboard + '\'' +
", display='" + display + '\'' +
'}';
}
}
这个是一个有可选参数的类吧。然后,我们创建一个
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:11:13
* 【Function】抽象的构建者
*/
public abstract class ComputerBuilder {
public abstract void setUsbCount();
public abstract void setKeyboard();
public abstract void setDisplay();
public abstract Computer getComputer();
}
这个是用来干什么的?先不要急,我们在写两个类你就知道了
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:12:49
* 【Function】联想电脑构建者类
*/
public class LenovoComputerBuilder extends ComputerBuilder {
private Computer computer;
public LenovoComputerBuilder(String cpu, String ram) {
computer=new Computer(cpu,ram);
}
@Override
public void setUsbCount() {
computer.setUsbCount(4);
}
@Override
public void setKeyboard() {
computer.setKeyboard("联想键盘");
}
@Override
public void setDisplay() {
computer.setDisplay("联想显示器");
}
@Override
public Computer getComputer() {
return computer;
}
}
再来一个
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:09:33
* 【Function】 目标类
*/
public class Computer {
private String cpu;//必须
private String ram;//必须
private int usbCount;//可选
private String keyboard;//可选
private String display;//可选
public Computer(String cpu, String ram) {
this.cpu = cpu;
this.ram = ram;
}
public void setUsbCount(int usbCount) {
this.usbCount = usbCount;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public void setDisplay(String display) {
this.display = display;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", usbCount=" + usbCount +
", keyboard='" + keyboard + '\'' +
", display='" + display + '\'' +
'}';
}
}
明白了吗? 上面两个类继承了最初的那个抽象类ComputerBuilder,目的就是为了用抽象类里面的方法,用于设置可选参数的值和获取到最后的电脑的信息。
只有这些吗?不,我们还缺少一个类
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:13:24
* 【Function】指导者类(Director)
*/
public class ComputerDirector {
public void makeComputer(ComputerBuilder builder){
builder.setUsbCount();
builder.setDisplay();
builder.setKeyboard();
}
}
这个是用来做什么呢?在笔者看来,它是最大的Boss,管理所有的构造者,它里面的makeComputer 方法可以看作是个构造器。传入的参数正是抽线类的实例ComputerBuilder 用于接收不同的电脑,无论是什么电脑都可以用它表示。传入电脑后,它就调用里面的setXXX方法,将可选的信息设置到对应的电脑里面。最后,我们来测试一下
package com.heigherjavatest.designpattern.builder;
/*
* 【Author】 技术支持史
* 【Time】2020年5月24日 下午2:15:02
* 【Function】
*/
public class Main {
public static void main(String[] args) {
//电脑指导者类
ComputerDirector director=new ComputerDirector();
// 构建苹果电脑
ComputerBuilder builder=new MacComputerBuilder("苹果I5处理器","苹果运行内存");
director.makeComputer(builder);//构建了
Computer macComputer=builder.getComputer();//构建之后 获得这个电脑的信息
System.out.println("我的苹果:"+macComputer.toString());
ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("联想I7处理器","联想运行内存");
director.makeComputer(lenovoBuilder);
Computer lenovoComputer=lenovoBuilder.getComputer();
System.out.println("我的联想:"+lenovoComputer.toString());
}
}
打印结果:
- 我的苹果:Computer{cpu=‘苹果I5处理器’, ram=‘苹果运行内存’, usbCount=2, keyboard=‘苹果键盘’, display=‘苹果显示器’}
- 我的联想:Computer{cpu=‘联想I7处理器’, ram=‘联想运行内存’, usbCount=4, keyboard=‘联想键盘’, display=‘联想显示器’}
看明白了吗?这里其实就是我创建了一个主要的电脑信息,其他的可选信息是通过构造者进行设置,最后输出的时候依然打印出来了,这样,我们就可以把主要注意力集中到主要参数上,不必关注可选参数,他们由构造器自动管理。
当中难免有纰漏,欢迎大家一起讨论补充!