建造者模式
建造者模式 是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们, 用户不需要知道内部的具体构建细节。
1、需要生成的产品对象有复杂的内部结构,这些产品对象具备共性
2、初始化一个对象时,参数过多,或者很多参数具有默认值
3、比如:建房子,不论什么房子都需要打地基、砌墙、封顶…而这些过程是不会变化的,变化的是你要盖豪华大楼还是茅草屋
需要建房子:这一过程为打桩、砌墙、封顶。不管是普通房子也好,别墅也好都需要经历这些过程,下面我们使用建
造者模式(Builder Pattern)来完成
1、普通方法
步骤如下:
1) 抽象房子类,让具体房型继承
2) 具体房型类,继承抽象房,完成某种房子的建造
3) 代码实现
AbstractHouse类
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public abstract class AbstractHouse {
//打地基
public abstract void buildBasic();
//砌 墙
public abstract void buildWalls();
//封 顶
public abstract void roofed();
public void build() {
buildBasic();
buildWalls();
roofed();
}
}
CommonHouse,继承AbstractHouse
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public class CommonHouse extends AbstractHouse {
@Override
public void buildBasic() {
// TODO Auto-generated method stub
System.out.println(" 普通房子打地基 ");
}
@Override
public void buildWalls() {
// TODO Auto-generated method stub
System.out.println(" 普通房子砌墙 ");
}
@Override
public void roofed() {
// TODO Auto-generated method stub
System.out.println(" 普通房子封顶 ");
}
}
客户端调用
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
CommonHouse commonHouse = new CommonHouse();
commonHouse.build();
}
}
优缺点:
1) 优点是比较好理解,简单易操作
2) 缺点是设计的程序结构,过于简单,没有设计缓存层对象,程序的扩展和维护不好. 也就是说,这种设计方案
,把产品(即:房子) 和 创建产品的过程(即:建房子流程) 封装在一起,耦合性增强了
2、利用建造者模式改进
大部分代码不变,只是把构造房子的步骤给了指挥者去执行,完成代码的解耦
步骤如下:
1) 抽象房子类,让具体房型继承
2) 具体房型类,继承抽象房,完成某种房子的建造
3) 指挥者类,指定制作流程,返回产品
4) 代码实现
HouseBuilder类
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public abstract class HouseBuilder {
//将建造的流程写好, 抽象的方法
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void roofed();
}
CommonHouse类
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public class CommonHouse extends HouseBuilder {
@Override
public void buildBasic() {
// TODO Auto-generated method stub
System.out.println(" 普通房子打地基5米 ");
}
@Override
public void buildWalls() {
// TODO Auto-generated method stub
System.out.println(" 普通房子砌墙10cm ");
}
@Override
public void roofed() {
// TODO Auto-generated method stub
System.out.println(" 普通房子屋顶 ");
}
}
HighBuilding省略,和CommonHouse大同小异
HouseDirector指挥者
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public class HouseDirector {
HouseBuilder houseBuilder = null;
//构造器传入 houseBuilder
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//如何处理建造房子的流程,交给指挥者
public void constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.roofed();
//return houseBuilder.buildHouse();
}
}
客户端调用
/**
* @author 漆剑
* @date 2021-03-27
* @description
*/
public class Client {
public static void main(String[] args) {
//盖普通房子
CommonHouse commonHouse = new CommonHouse();
//准备创建房子的指挥者
HouseDirector houseDirector = new HouseDirector(commonHouse);
//完成盖房子,返回产品(普通房子)
houseDirector.constructHouse();
System.out.println("--------------------------");
//盖高楼
HighBuilding highBuilding = new HighBuilding();
//重置建造者
houseDirector = new HouseDirector(highBuilding);
//完成盖房子,返回产品(高楼)
houseDirector.constructHouse();
}
}
- 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,因此在这种情况下,要考虑是否选择建造者模式.
由于水平有限,本博客难免有不足,恳请各位大佬不吝赐教!