建造者模式,又称为生成器模式,将复杂对象的构建过程抽象.使不同的实现方法可以构造出不同的对象,内部构建过程透明.有四个角色,这四个角色并不是必然存在的,因为设计模式本就是大而无形,有的只是个思想.
产品角色(Product), 构建出的结果,具体的产品对象
抽象建造者(Builder), 创建一个产品对象的各个部件,指定的接口/抽象类
具体建造者(ConcreteBuilder), 实现接口构建和组装各个部件
指挥者(Director),构建一个使用抽象建造者的对象,用于创建复杂对象,隔离生成过程,控制产品对象生产过程
作者是个二吊子,如果描述有误请指出.
使用场景
我们在构建一个产品时(这时候就有了产品角色),这个产品可能有不同的行为过程,而这些过程我们不想知道,所以我们就有了抽象建造者,抽象建造者是规范了行为,将行为进行抽象.没有具体实现.当我们需要建造一个产品时,我们需要有具体的实现类(具体建造者).由它来实现抽象建造者中定义的各种行为.进行自定义实现.但是以上三个角色虽然有依赖关系存在.但是却没有统一的入口,如果我们由抽象建造者进行多态来进行调用,那么我们的行为规范可能就会受到破坏.因为我们的行为往往都是具有顺序性的.这时候就引入了指挥者,由它来控制进度和顺序,以及提供统一对外接口.
举个扯淡的例子, .就像建房子,我们要知道进度或者建一个房子,虽然你可以直接去找搬砖工程师,刷墙工程师,抬杠工程师.
你来进行协调让他们搞.但是你这样只能建一个房子,你又不专业,这样可能就搞出了豆腐渣.
那么我们就需要来进行规范化.这个时候一个脑回路清奇的哥们就说,我们出个搬砖手册吧,上面写我们谁该干嘛,于是就有了搬砖手册(抽象建造者),
但是这个只是一个规范,我们要实施还是不一样的,搬砖工程师就具体定义了我们该怎么搬砖,他们实现了一个具体的行为规范,抬杠工程师定义了该怎么抬杠,刷墙的定义了具体怎么喷.这些具体定义都来自手册(抽象建造者).这些具体的行为规范就成了工程师的自我修养(具体建造者).
但是这么搞还是不对劲啊,这tm 我才搬了砖过来还没贴,这个刷墙的哥们就喷上了,这顺序不低啊,抬杠的哥们发现钢筋抬过来了,这搬砖的把墙都砌好了.这谁顶得住,钢筋还没用墙就有了.墙还没砌,刷墙就开始喷了.一切都是这么不可思议.
于是乎,工地又招了一个包工头,这哥们久经沙场知道该怎么砌房子怎么跟客户扯皮.于是他负责协调和对外.让搬砖的先把砖拿过来,抬杠的把钢筋整到位.然后砌墙,刷墙.大家就这么干起来了.房子也成了.
建造者模式雏形
uml图
我们最开始的样子,考虑了房子的估计行为顺序,但是我们只是定义了行为和行为的顺序执行,由具体实现来做具体的工作,比如CommonHouse 可以理解为具体建造者,这个也可以理解为一个工程队,每个工程队都可以干这些事情,但是搞得过程是五花八门,有些杀鸡祭天的有些杀工程师的.这样子我们在用的时候直接多态用组合或者聚合都可以使用.但是这样扩展性不是很好,我们新加一个具体建造者,也就是工程队,那么我们在客户端使用的时候就会用到,如果后边要去掉一个,就很五花八门了.由此,这个做法是不成熟的,只能是小公司做派,管理制度不完善,拍脑袋想事情.
/**
* @Description: 最初版的抽象建造者
* @Author: gaofan
* @Date: 2020/3/21 15:36
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public abstract class AbstractHouse {
// 打地基
public abstract void buildBasic();
// 砌墙
public abstract void buildWall();
// 封底
public abstract void roofed();
public void build(){
buildBasic();
buildWall();
roofed();
}
}
/**
* @Description: 好理解,易操作,增加了耦合性.把产品和行为过程封装在一起
* @Author: gaofan
* @Date: 2020/3/21 15:38
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class CommonHouse extends AbstractHouse {
@Override
public void buildBasic() {
System.out.println("普通房子打地基");
}
@Override
public void buildWall() {
System.out.println("普通房子砌墙");
}
@Override
public void roofed() {
System.out.println("普通房子封顶");
}
}
/**
* @Description: TODO
* @Author: gaofan
* @Date: 2020/3/21 15:39
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class Client {
public static void main(String [] args){
AbstractHouse houseBuild = new CommonHouse();
houseBuild.build();
}
}
类型: 初期建造者的雏形
原理: 通过产品和行为整合到一起实现的,分类不是很细化,如果后期有增加或者修改会比较不合理,单一性不好,我从这里看到了模板模式的咸味了.
建造者模式
在抽象的基础上越走越远.将产品与行为进行划分.初期的建造者只注重了行为.虽然建造者模式其主要的限定操作是行为,但是这并不代表能抛弃产品.而建造者模式对他们进行划分.
uml图
这就是比较完善的一个体制,各司其职,是对单一性原则进行的反复阐述.如不懂,可以借鉴开始的那个举例,如果看完了还是不懂,那多半是博主菜鸡没写好,请留言备注,轻喷
/**
* @Description: 抽象建造者
* @Author: gaofan
* @Date: 2020/3/21 15:56
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public abstract class HouseBuilder {
protected House house = new House();
public abstract void buildBasic();
public abstract void buildWall();
public abstract void roofed();
public House build(){
return house;
}
}
/**
* @Description: 具体建造者
* @Author: gaofan
* @Date: 2020/3/21 15:59
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class HightBuilding extends HouseBuilder {
@Override
public void buildBasic() {
super.house.setBasic("高层房子打地基-50米");
System.out.println("高层房子打地基-50米");
}
@Override
public void buildWall() {
super.house.setWall("高层房子砌墙-100cm");
System.out.println("高层房子砌墙-100cm");
}
@Override
public void roofed() {
super.house.setRoofed("高层房子封底");
System.out.println("普通房子封底");
}
}
/**
* @Description: 具体建造者
* @Author: gaofan
* @Date: 2020/3/21 15:58
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class CommonHouse extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println("普通房子打地基-5米");
}
@Override
public void buildWall() {
System.out.println("普通房子砌墙-10cm");
}
@Override
public void roofed() {
System.out.println("普通房子封底");
}
}
/**
* @Description: 产品
* @Author: gaofan
* @Date: 2020/3/21 15:55
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class House {
private String basic;
private String wall;
private String roofed;
public House() {}
public String getBasic() {
return basic;
}
public void setBasic(String basic) {
this.basic = basic;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoofed() {
return roofed;
}
public void setRoofed(String roofed) {
this.roofed = roofed;
}
@Override
public String toString() {
return "House{" +
"basic='" + basic + '\'' +
", wall='" + wall + '\'' +
", roofed='" + roofed + '\'' +
'}';
}
}
/**
* @Description: 指挥者
* @Author: gaofan
* @Date: 2020/3/21 16:01
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class HouseDirector {
HouseBuilder houseBuilder = null;
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
// 如何建造房子,指挥者处理
public House buildHouse(){
houseBuilder.buildBasic();
houseBuilder.buildWall();
houseBuilder.roofed();
return houseBuilder.build();
}
}
/**
* @Description: TODO
* @Author: gaofan
* @Date: 2020/3/21 16:06
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class Client {
public static void main(String [] args){
CommonHouse commonHouse = new CommonHouse();
HouseDirector director = new HouseDirector(commonHouse);
House house = director.buildHouse();
System.out.println(house.toString());
}
}
类型: 建造者模式
原理: 将行为和产品区分,属于创建型设计模式,目的是为了创建对象实例.但是个人理解建造者模式注重行为的整合,具体建造者类提供具体实现,然后指挥者进行拼装分配,从而达到组装对象实例的目的.与抽象工厂模式不同的是,抽象工厂模式返回一类产品,以产品划分.这里是根据行为整合的一种方式,说像也像,说不像也不像.感觉学了设计模式也学会了什么叫 似是而非…
缺点: 编码会增多
本文借鉴尚硅谷Java设计模式,韩顺平图解java,传送门