建造者模式
定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
使用场景:当一个类的构造函数参数个数超过四个,而这些参数有些是可选参数,考虑使用建造者模式。
为什么要使用建造者模式?
当一个类的构造函数参数大于4,且有些参数为可选时。通常实例化对象有两种方式:
- 使用构造器实例化对象。
- 使用JavaBean,setter方法实例化对象。
第一种实例化对象方式,需要编写不同的构造函数,在成员变量非常多的情况下需要根据可变的成员变量,来编写大量不同的构造函数,灵活性较差,参数类型相似时实际调用时不方便。
第二种实例化对象方式,属性的设置是分开的,代码复杂的情况下可能会出现设置属性遗漏或出错的情况。
建造者模式的优点
- 建造者模式将类的构造函数中的可选参数分离出来,使用setter的方式进行初始化,非常的灵活。
- 建造者模式是链式调用,属性连续设置,当调用build()方法实例化对象后对象不可再进行改变,看起来是一个整体,较简洁,易于程序员阅读和管理。
代码
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 + '\'' +
'}';
}
}
public abstract class ComputerBuilder {
public abstract void setUsbCount();
public abstract void setKeyboard();
public abstract void setDisplay();
public abstract Computer getComputer();
}
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("Lenovo Keyboard");
}
@Override
public void setDisplay() {
computer.setDisplay("Lenovo Display");
}
@Override
public Computer getComputer() {
return computer;
}
}
public class MacComputerBuilder extends ComputerBuilder {
private Computer computer;
public MacComputerBuilder(String cpu, String ram) {
computer = new Computer(cpu, ram);
}
@Override
public void setUsbCount() {
computer.setUsbCount(2);
}
@Override
public void setKeyboard() {
computer.setKeyboard("Mac Keyboard");
}
@Override
public void setDisplay() {
computer.setDisplay("Mac Display");
}
@Override
public Computer getComputer() {
return computer;
}
}
public class Director {
public void makeComputer(ComputerBuilder builder){
builder.setUsbCount();
builder.setDisplay();
builder.setKeyboard();
}
public static void main(String[] args) {
Director director=new Director();//1
ComputerBuilder builder=new MacComputerBuilder("I5","Samsung 125");//2
director.makeComputer(builder);//3
Computer macComputer=builder.getComputer();//4
System.out.println("mac computer:"+macComputer.toString());
ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("I7","Hynix 222");
director.makeComputer(lenovoBuilder);
Computer lenovoComputer=lenovoBuilder.getComputer();
System.out.println("lenovo computer:"+lenovoComputer.toString());
}
}
mac computer:Computer{cpu='I5', ram='Samsung 125', usbCount=2, keyboard='Mac Keyboard', display='Mac Display'}
lenovo computer:Computer{cpu='I7', ram='Hynix 222', usbCount=4, keyboard='Lenovo Keyboard', display='Lenovo Display'}