Java设计模式 之 建造者模式Builder
我们日常新建对象,比如手机,包含CPU,屏幕,ID号,手机名等参数,代码如下:
//Cpu
public class Cpu {
private String name;
public Cpu(String name) {
this.name = name;
}
@Override
public String toString() {
return "cpu:" + name;
}
}
//屏幕
public class Screen {
private String name;
public Screen(String name) {
this.name = name;
}
@Override
public String toString() {
return "Screen:" + name;
}
}
苹果手机 IPhoneX:
public class IPhone {
private String name;
private int id;
private Cpu cpu;
private Screen screen;
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public void setScreen(Screen screen) {
this.screen = screen;
}
@Override
public String toString() {
return name + " " + id + " " + cpu+ " " +screen;
}
}
public class CreateDemo {
public static void main(String[] args) {
IPhone iPhone = new IPhone();
iPhone.setId(100);
iPhone.setCpu(new Cpu("a11"));
iPhone.setName("iPhone");
iPhone.setScreen(new Screen("OLED"));
System.out.println(iPhone);
// 输出
// iPhone 100 cpu:a11 Screen:OLED
}
}
我们会发现一个正常的新建对象new出来了,但假设我们这个手机需要增加其他可选择参数,我们会发现一直设置下来会很麻烦。
我们接着尝试另一种写法,代码如下:
public class XiaomiPhone {
private String name;
private int id;
private Cpu cpu;
private Screen screen;
public XiaomiPhone setName(String name) {
this.name = name;
return this;
}
public XiaomiPhone setId(int id) {
this.id = id;
return this;
}
public XiaomiPhone setCpu(Cpu cpu) {
this.cpu = cpu;
return this;
}
public XiaomiPhone setScreen(Screen screen) {
this.screen = screen;
return this;
}
@Override
public String toString() {
return name + " " + id + " " + cpu+ " " +screen;
}
}
再次新建对象,代码如下:
public class CreateDemo {
public static void main(String[] args) {
XiaomiPhone xiaomiPhone = new XiaomiPhone();
xiaomiPhone
.setId(200)
.setCpu(new Cpu("xiaolong835"))
.setName("xiaomi")
.setScreen(new Screen("LED"));
System.out.println(xiaomiPhone);
// 输出
// xiaomi 200 cpu:xiaolong835 Screen:LED
}
}
我们发现这种写法对应多个参数,有很好的选择,那能否一次性新建起来呢?
建造者模式Builder
这是时候可以用Builder模式,
public class HuaweiPhone {
private String name;
private int id;
private Cpu cpu;
private Screen screen;
public HuaweiPhone() {
}
public HuaweiPhone(HuaweiPhone huaweiPhone) {
this.name = huaweiPhone.name;
this.id = huaweiPhone.id;
this.cpu = huaweiPhone.cpu;
this.screen = huaweiPhone.screen;
}
@Override
public String toString() {
return name + " " + id + " " + cpu + " " + screen;
}
public static class Builder {
private HuaweiPhone target;
public Builder() {
target = new HuaweiPhone();
}
public Builder setName(String name) {
target.name = name;
return this;
}
public Builder setId(int id) {
target.id = id;
return this;
}
public Builder setCpu(Cpu cpu) {
target.cpu = cpu;
return this;
}
public Builder setScreen(Screen screen) {
target.screen = screen;
return this;
}
public HuaweiPhone builder() {
return new HuaweiPhone(target);
}
}
}
再次新建对象:
public class CreateDemo {
public static void main(String[] args) {
HuaweiPhone huaweiPhone
= new HuaweiPhone.Builder()
.setName("huawei")
.setId(300)
.setCpu(new Cpu("qiling970"))
.setScreen(new Screen("LED"))
.builder();
System.out.println(huaweiPhone);
}
}
看完上面的代码,我们可以利用Builder来构建对象,发现可以根据需要设置我们对应的参数,在builder()之后会返回一个对象。初次看我们可能不能接受,这种结构,我们在把这个builder进行分解,代码如下:
// 相当与Builder
public class PhoneBuilder {
private HuaweiPhone target;
public PhoneBuilder() {
target = new HuaweiPhone();
}
public PhoneBuilder setName(String name) {
target.name = name;
return this;
}
public PhoneBuilder setId(int id) {
target.id = id;
return this;
}
public PhoneBuilder setCpu(Cpu cpu) {
target.cpu = cpu;
return this;
}
public PhoneBuilder setScreen(Screen screen) {
target.screen = screen;
return this;
}
// 相当与builder()
public HuaweiPhone create() {
return new HuaweiPhone(target);
}
}
//导向器 中间者 管理建造出来的实例的依赖关系
public class PhoneDirector {
PhoneBuilder builder;
public PhoneDirector(PhoneBuilder builder) {
this.builder = builder;
}
public void setName(String name) {
builder.setName(name);
}
public void setId(int id) {
builder.setId(id);
}
public void setCpu(Cpu cpu) {
builder.setCpu(cpu);
}
public void setScreen(Screen screen) {
builder.setScreen(screen);
}
// 相当与builder
public HuaweiPhone create() {
return builder.create();
}
}
public class CreateDemo {
public static void main(String[] args) {
PhoneBuilder builder = new PhoneBuilder();
PhoneDirector director = new PhoneDirector(builder);
director.setCpu(new Cpu("qiling970"));
director.setId(400);
director.setName("huawei");
director.setScreen(new Screen("OLED"));
HuaweiPhone huaweiPhone2 = director.create();
System.out.println(huaweiPhone2);
// 输出 huawei 300 cpu:qiling970 Screen:OLED
}
}
手机构造使用了导向器来构建,构建了 PhoneBuilder 中的 华为手机,但是上述代码是可以缩减的,合起来就是我们上述的 简约的builder模式。
我们最后来总结下这个模式:
建造者模式Builder
目的:
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示,
比如将上述的华为手机换成小米手机
主要解决:
主要解决在软件系统中,有时候面临着”一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。比如各种方法的固定使用,而实现的类不同
何时使用:
一些基本部件不会变,而其组合经常变化的时候。
如何解决:
将变与不变分离开。比如手机的品牌的替换,将手机的方法抽象成抽象方式,而对象可以改变,可使用接口或者抽象类解决
关键代码:
建造者(PhoneBuilder):创建和提供实例,导演(PhoneDirector ):管理建造出来的实例的依赖关系。
其他模式可点击链接进目录阅读了解:http://blog.csdn.net/xiao_wanzi94/article/details/78118092