前言
-
- 建造者模式也叫生成器模式,作为设计模式里五个创建者模式之一,它的作用也是为了创建对象,但是不同于其他模式直接new的方式,它的存在是为了创建复杂的对象,因此创建之路一波三折。
- 同工厂模式相似,建造者模式也是完成了对创建对象程序的封装,达到了要用就拿的效果。
- 关于什么是复杂的对象,如果要用的时候直接new出来的就不复杂,复杂的对象复杂在为了达到某种作用,我们需要对某些对象进行属性值的注入,行为的更改,使对象更丰满,然后在拿到该对象,简而言之,建造者模式对对象进行某些包装,这样拿到的对象就是我们需要的。
情景引入
下面我们举例来看什么是建造者模式,建造者模式在我们构建对象过程中发挥了哪些作用。支付宝里有个小游戏叫蚂蚁庄园,里面的养的小鸡通过吃饲料产生爱心,而小鸡又有多种套装可选,能随意组合,本例中我们就以套装为对象,进行创建和包装(先看懂程序,我们在分析它)。
建造者的几种角色
抽象建造者(builder) | 它声明为创建一个Product对象的各个部件指定的抽象接口。 |
具体建造者(ConcreteBuilder) | 实现抽象接口,构建和装配各个部件。 |
指挥者(director) | 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象,它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。 |
产品角(product) | 一个具体的产品对象。 |
我程序的类图
java源程序
套装类
package builder;
public class Suit {//蚂蚁庄园小鸡套装
String hat;//帽子
String glasses;//眼镜
String clothes;//衣服
String food;//食物
public void suitShow(){
System.out.println("限量版的 " +hat+" "+glasses+" "+clothes+" "+food+" 套装");
}
public String getHat() {
return hat;
}
public void setHat(String hat) {
this.hat = hat;
}
public String getGlasses() {
return glasses;
}
public void setGlasses(String glasses) {
this.glasses = glasses;
}
public String getClothes() {
return clothes;
}
public void setClothes(String clothes) {
this.clothes = clothes;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
}
抽象建造者
抽象的建造者,里面维护了一个套装类的实例,而且里面声明了一些对套装类操作的抽象方法和实例返回方法,很明显子类可以对套装类对象进行操作并把对象完整返回
package builder;
public abstract class SuitBuilder {
Suit suit = new Suit();
public Suit getSuit() {
return suit;
}
public abstract void setHat();
public abstract void setGlasses();
public abstract void setClothes();
public abstract void setFood();
}
具体建造者(时尚套装)
package builder;
//时尚的套装
public class FashionSuitBuilder extends SuitBuilder{
public void setHat() {
suit.setHat("麦克帽子");
}
public void setGlasses() {
suit.setGlasses("华丽眼镜");
}
public void setClothes() {
suit.setClothes("熊孩子外套");
}
public void setFood() {
suit.setFood("野葡萄");
}
}
具体建造者(简约套装)
package builder;
//简约的套装
public class SimpleSuitBuilder extends SuitBuilder{
public void setHat() {
suit.setHat("土豪金帽子");
}
public void setGlasses() {
suit.setGlasses("花呗眼镜");
}
public void setClothes() {
suit.setClothes("丽丽上衣");
}
public void setFood() {
suit.setFood("西伯利亚野苹果");
}
}
指导者
指导者负责创建对象,里面包含了建造者的引用,在constructor方法里,通过指挥建造者对对象进行创建包装,取得建造完成的对象,在拿给客户端。
package builder;
public class SuitDirector {
SuitBuilder asb;
public SuitDirector(SuitBuilder asb) {
this.asb=asb;
}
public Suit constructor(){
//建造者完成对对象的创建
asb.setHat();
asb.setClothes();
asb.setFood();
asb.setGlasses();
return asb.getSuit();//返回包装完成的对象
}
}
客户端
package builder;
public class Client {
public static void main(String[] args) {
SuitBuilder sb = new FashionSuitBuilder();//生成具体建造者
SuitDirector sd = new SuitDirector(sb);//生成指导者
Suit s = sd.constructor();//创建套装
s.suitShow();
}
}
运行结果
程序分析
- 程序运行步骤我在例子中已经说明了,现在我们看一下建造者模式中各个角色的用途,建造者模式通过创建对象包装对象的方式完成了对复杂对象的构建。
- 首先我们的产品套装类,只是简单的产品,建造者则是以他为基础进行构建,抽象建造者定义了建造方式,而具体建造者则定义对对象的行为操作属性的创建的具体方式,而真正具有创建权的则是指导者,指导者决定了建造者要建造哪些东西,然后指导者把建造完成的对象拿给客户。
现在我们在回头看看建造者模式
定义
使用建造者模式封装一个产品的构造过程,并允许按步骤构造。
应用场景
- 需要生成的产品对象具有复杂的内部结构
- 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
应用到的设计原则
- 高内聚,低耦合,建造者模式对对象的构建实现了良好的封装,与客户进行了解耦
- 开闭原则,扩展建造者类只要实现建造者抽象类就可以,不用更改原有代码
建造者模式优点
-
- 将复杂对象的创建过程封装起来,实现了与客户端的解耦
- 允许对象通过多个步骤来创建,并且可以改变过程
- 产品的实现可以被替换
缺点
建造者模式建造的对象一般具有较多的共同点,如果差异性较大,则没办法使用这个模式