大家好,欢迎来到IT知识分享网。
了解建造者模式?
建造者模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
从概念中可以看到2个重要的信息:一是构建和表示是分离的,二是通过同一个构建过程,能获得不同的实例对象。
建造者模式的角色:
-
Product产品类:具体完整的产品。
-
Builder抽象建造者:规范产品的组件,一般是由子类实现实现具体的组建过程。
-
ConcreteBuilder具体建造者:实现抽象类定义的所有方法,并返回一个组建好的对象。
-
Director指挥者:统一组建过程,负责安排已有模块的顺序,然后告诉Builder开始建造。
什么时候需要考虑使用建造者模式?
从建造者模式的定义中,可以看出建造者模式处理的是构建对象的过程,在java中,构建对象涉及到的有构造器和参数。
如果一个对象构建的时候,参数比较多,4个以上,而且参数是可选择的,那么这个时候,就可以考虑使用建造者模式来优化构建对象的过程。
普通的构建过程
现在我们需要一个电脑对象,电脑对象包含主板、内存、cpu、显示器和键盘。其中,主板、内存和cpu是必须的,显示器和键盘是可选的。
public class Computer {
private String mBoard;
private String cpu;
private String ram;
private String Display;
private String keyboard;
public Computer(String mBoard, String cpu, String ram) {
this.mBoard = mBoard;
this.cpu = cpu;
this.ram = ram;
}
public void setDisplay(String display) {
Display = display;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
@Override
public String toString() {
return "Computer{" +
"mBoard='" + mBoard + '\'' +
", cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", Display='" + Display + '\'' +
", keyboard='" + keyboard + '\'' +
'}';
}
public static void main(String[] args) {
Computer hwComp = new Computer("华硕z-01","英特尔-i7","海盗船D01");
hwComp.setDisplay("华为显示器");
hwComp.setKeyboard("华为键盘");
System.out.println(hwComp.toString());
//Computer{mBoard='华硕z-01', cpu='英特尔-i7', ram='海盗船D01',
//Display='华为显示器', keyboard='华为键盘'}
Computer lenovoComp = new Computer("微星z-01","AMD推土机","三星S02");
lenovoComp.setDisplay("联想显示器");
lenovoComp.setKeyboard("联想键盘");
System.out.println(lenovoComp.toString());
//Computer{mBoard='微星z-01', cpu='AMD推土机',
//ram='三星S02', Display='联想显示器', keyboard='联想键盘'}
}
}
使用普通的构建过程,调用者需要知道构建过程中填入的参数和意义是什么,而且可选的参数也都要自己去设置。如果参数少的情况,还能接受,如果是实际开发,有些对象需要初始化的参数就有7,8个,而且在如果是这么写的话,对象的构造过程是不可控的,完全依赖于开发人员,有可能在运行过程中,对象遗漏了参数导致对象不完整,出现bug。这个时候通过构造者模式来解决这个问题。
如何实现建造者模式?
- 首先需要定义一个需要用到的产品,以及产品需要使用到的参数。通过构造函数,指定产品必须定义的参数,可选参数提供对应的set方法。
public class Computer {
private String mBoard;
private String cpu;
private String ram;
private String Display;
private String keyboard;
public Computer(String mBoard,String cpu,String ram ) {
this.mBoard = mBoard;
this.cpu = cpu;
this.ram = ram;
}
public void setDisplay(String display) {
Display = display;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
@Override
public String toString() {
return "Computer{" +
"mBoard='" + mBoard + '\'' +
", cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", Display='" + Display + '\'' +
", keyboard='" + keyboard + '\'' +
'}';
}
}
- 定义一个Builder对象,规范产品的组件
public abstract class Builder {
public abstract void buildKeyboard();
public abstract void buildDisplay();
public abstract Computer build();
}
- 然后通过具体的Builder对象,实现具体的构建过程
public class HuaweiCompBuilder extends Builder {
private Computer computer;
public HuaweiCompBuilder(String mBoard, String cpu, String ram) {
this.computer = new Computer(mBoard,cpu,ram);
}
@Override
public void buildKeyboard() {
computer.setKeyboard("华为键盘");
}
@Override
public void buildDisplay() {
computer.setDisplay("华为显示器");
}
@Override
public Computer build() {
return computer;
}
}
public class LenovoCompBuilder extends Builder{
private Computer computer;
public LenovoCompBuilder(String mBoard, String cpu, String ram) {
this.computer = new Computer(mBoard,cpu,ram);
}
@Override
public void buildKeyboard() {
computer.setKeyboard("联想键盘");
}
@Override
public void buildDisplay() {
computer.setDisplay("联想显示器");
}
@Override
public Computer build() {
return computer;
}
}
- 最后提供一个Director对象,负责安排构建顺序,统一构建过程。
public class Director {
public void construct(Builder builder){
builder.buildDisplay();
builder.buildKeyboard();
}
}
- 最后,开发人员通过具体的子类,来获取需要的对象
Builder builder = new HuaweiCompBuilder("华硕z-01","英特尔-i7","海盗船D01");
Director pcDir = new Director();
pcDir.construct(builder);
Computer computer = builder.build();
//Computer{mBoard='华硕z-01', cpu='英特尔-i7', ram='海盗船D01',
//Display='华为显示器', keyboard='华为键盘'}
System.out.println(computer.toString());
Builder lenovoCompBuilder = new LenovoCompBuilder("微星z-01","AMD推土机","三星S02");
Director lenDic = new Director();
lenDic.construct(lenovoCompBuilder);
Computer lenComputer = lenovoCompBuilder.build();
//Computer{mBoard='微星z-01', cpu='AMD推土机', ram='三星S02',
//Display='联想显示器', keyboard='联想键盘'}
System.out.println(lenComputer.toString());
开发人员通过Builder的具体子类,然后通过Director对象实现构建过程,最终通过Builder对象获取构建好的对象。这是传统的建造者模式的实现方法。
简化实现过程
在传统的建造者模式实现过程中,需要通过Director对象来统一组建过程,但其实很多时候调用者本身就知道需要怎么去构建自己想要的对象,所以可以把Director这个角色去掉,简化建造者模式
public class ComputerSim {
private String mBoard;
private String cpu;
private String ram;
private String display;
private String keyboard;
public ComputerSim(Builder builder) {
this.mBoard = builder.mBoard;
this.cpu = builder.cpu;
this.ram = builder.ram;
this.display = builder.display;
this.keyboard = builder.keyboard;
}
public static class Builder {
private String mBoard;
private String cpu;
private String ram;
private String display;
private String keyboard;
public Builder(String mBoard,String cpu,String ram){
this.mBoard = mBoard;
this.cpu = cpu;
this.ram = ram;
}
public Builder setDisplay() {
this.display = "华为显示器";
return this;
}
public Builder setKeyboard() {
this.keyboard = "华为键盘";
return this;
}
public ComputerSim build(){
return new ComputerSim(this);
}
}
@Override
public String toString() {
return "ComputerSim{" +
"mBoard='" + mBoard + '\'' +
", cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", display='" + display + '\'' +
", keyboard='" + keyboard + '\'' +
'}';
}
public static void main(String[] args) {
ComputerSim computerSim = new ComputerSim.Builder("华硕z-01","英特尔-i7",
"海盗船D01").setDisplay().setKeyboard().build();
//ComputerSim{mBoard='华硕z-01', cpu='英特尔-i7',
// ram='海盗船D01', display='华为显示器', keyboard='华为键盘'}
System.out.println(computerSim);
}
}
简化版通过静态内部类的方式,来实现对象的构建,每一步通过返回构造对象,来实现链式引用,简化了实现过程。
总结
建造者模式,统一了复杂对象的构建过程,这在提供统一的服务时尤为明显,在spring、mybatis这些框架中,就有很多建造者模式的应用实例。感兴趣的可以看看在这些框架中,是怎么去应用建造者模式的。
💖 看完小事件
如果你觉得这篇内容对你有一点帮助或启发,想请你动动小指拇:
点赞,让更多的人也能看到这篇内容(收藏加点赞,永远不慌张(乛◡乛))。
关注公众号[ 撸透JAVA开发 ],不定期分享原创知识。
溜达溜达公众号,看看其他文章是否对你也有启发。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/13901.html