1 Builder Pattern 建造者模式
目的:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示;
实现:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
在以下情况下可以考虑使用建造者模式:
1.需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性;
2.需要生成的产品对象的属性相互依赖,需要指定其生成顺序;
3.对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中;
4.隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
2 实现
代码场景:战国时期各诸侯国为了在争霸中处于有利地位和不被别国吞并出现了很多变法运动,魏国李悝 ,楚国吴起 ,秦国商鞅 ,韩国申不害等,各诸侯通过这些人才对国家进行了一系列改革使国家焕然一新。
2.1 代码实现
产品类:国家
public class Country {
//国家的名字
private String countryname;
//国家的政治
private String polotics;
//国家的军事
private String army;
//国家的农业
private String agriculture;
//国家的新面貌
private String buildResult;
public String getCountryname() {
return countryname;
}
public void setCountryname(String countryname) {
this.countryname = countryname;
}
public String getPolotics() {
return polotics;
}
public void setPolotics(String polotics) {
this.polotics = polotics;
}
public String getArmy() {
return army;
}
public void setArmy(String army) {
this.army = army;
}
public String getAgriculture() {
return agriculture;
}
public void setAgriculture(String agriculture) {
this.agriculture = agriculture;
}
public String getBuildResult() {
return buildResult;
}
public void setBuildResult(String buildResult) {
this.buildResult = buildResult;
}
//展示国家风采
public void showPower() {
System.out.println("国家:" + countryname);
System.out.println("政治:" + polotics);
System.out.println("军事:" + army);
System.out.println("农业:" + agriculture);
System.out.println("结果:" + buildResult);
System.out.println("-----------------------");
}
}
建造者抽象类
public abstract class Builder {
//政治改革
public abstract void buildPolotics();
//军事改革
public abstract void buildArmy();
//农业改革
public abstract void buildAgriculture();
//改革成果
public abstract Country getCountry();
}
具体建造者商鞅:对秦国进行了一些了改革
public class ShangYangBuilder extends Builder {
//为秦国进行改革
private Country qin = new Country();
@Override
public void buildPolotics() {
qin.setPolotics("中央集权,推行县制");
qin.setCountryname("秦");
}
@Override
public void buildArmy() {
qin.setArmy("励军功,实行二十等爵制");
}
@Override
public void buildAgriculture() {
qin.setAgriculture("废井田,开阡陌");
qin.setBuildResult("日渐强盛,收复失地,终一统天下!");
}
@Override
public Country getCountry() {
return qin;
}
}
具体建造者申不害:对韩国进行了一些了改革
public class ShenBuHaiBuilder extends Builder {
//为韩国进行改革
private Country han = new Country();;
@Override
public void buildPolotics() {
han.setPolotics("整顿吏治,加强君主集权统治");
han.setCountryname("韩");
}
@Override
public void buildArmy() {
han.setArmy("整肃军兵,严酷训练");
}
@Override
public void buildAgriculture() {
han.setAgriculture("多开荒地,多种粮食");
han.setBuildResult("政局得到稳定,贵族受到限制,百姓渐趋富裕!");
}
@Override
public Country getCountry() {
return han;
}
}
导演类: 诸侯
//director导演角色
public class King {
//诸侯授权变法者执行变法
public Country authorizeConstruct(Builder b) {
b.buildPolotics();
b.buildArmy();
b.buildAgriculture();
return b.getCountry();
}
}
2.2 涉及角色
在建造者模式结构图中包含如下几个角色:
Builder(抽象建造者):它为创建一个产品 Product 对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是 buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是 getResult(),它们用于返回复杂对象。Builder 既可以是抽象类,也可以是接口。
ConcreteBuilder(具体建造者):它实现了 Builder 接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者 Setter 方法将该对象传入指挥者类中。
2.3 调用
调用者
public class Client {
public static void main(String[] args) {
// 发法执行人:申不害
Builder shenBuHai = new ShenBuHaiBuilder();
// 发法执行人:商鞅
Builder shangYang = new ShangYangBuilder();
// 诸侯
King king = new King();
// 诸侯授权执行变法
Country han = king.authorizeConstruct(shenBuHai);
Country qin = king.authorizeConstruct(shangYang);
han.showPower();
qin.showPower();
}
}
结果:
国家:韩
政治:整顿吏治,加强君主集权统治
军事:整肃军兵,严酷训练
农业:多开荒地,多种粮食
结果:政局得到稳定,贵族受到限制,百姓渐趋富裕!
-----------------------
国家:秦
政治:中央集权,推行县制
军事:励军功,实行二十等爵制
农业:废井田,开阡陌
结果:日渐强盛,收复失地,终一统天下!
-----------------------
建造者与工厂模式的区别:
建造者模式:注重生产产品的行为
工厂模式:注重生产产品的属性
代码地址:点击跳转
参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.