一、建造者模式(Builder)的定义
建造者模式是相对比较简单的一种设计模式,属于创建型模式的一种;定义:将一个复杂的对象分解成多个简单的对象来进行构建,将复杂的构建层与表现层分离,使相同的构建过程可以创建不同的表示模式。
简单例子来说:当我们在外面饭店吃饭时,比如点个水煮肉片,这家店可能会辣一点、那家店可能会咸一点、对面那家可能放青菜、隔壁那家可能放菠菜,每家店做出来的都不一样,明明都是水煮肉片却有不同的做法,如果都一样就不会说这家难吃那家好吃了。那再看KFC,我们点个汉堡,所有人不管在哪个城市哪家店,做法、味道都是一样的,为什么呢,因为它用料、时间、温度等等都是严格规定的,我们只需要下订单就行了,这就是一个建造者模式。
二、模式的结构
建造者模式的主要角色如下:
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
建造者模式结构图如下:
三、模式的实现
1. 建造者模式我们在代码中经常用到,比如Jquery中的ajax请求:
//1 用户发送一个请求
//2 $.ajax建造者模式(指挥者)
//3 具体实现 (建造者)
$.ajax({
url:'www.juejin.cn',
success:function(argument){ }
});
2.其中主要流程实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
</body>
<script>
//商店:Director指挥者类
function KFCShop() {
this.construct = function(builder) {
builder.step1();
builder.step2();
return builder.get();
}}
//汉堡包制作:建造者类
function HamburgerBuilder() {
this.bread = null;
this.step1 = function() {
this.bread = new Hamburger();
};
this.step2 = function() {
this.bread.addQuantity();
};
this.get = function() {
return this.bread;
};
}
//薯条制作:建造者类
function FrenchFriesBuilder() {
this.fries = null;
this.step1 = function() {
this.fries = new FrenchFries();
};
this.step2 = function() {
this.fries.addQuantity();
};
this.get = function() {
return this.fries;
};
}
//产品类:汉堡包
function Hamburger() {
this.quantity = 1;
this.addQuantity = function() {
this.quantity = 6;
};
this.say = function() {
log.add("我要" + this.quantity + "个汉堡包!");
};
}
//产品类:薯条
function FrenchFries() {
this.quantity = 1;
this.addQuantity = function() {
this.quantity = 2;
};
this.say = function() {
log.add("我要" + this.quantity + "份薯条!");
};
}
// 日志打印
var log = (function() {
var log = "";
return {
add: function(msg) {
log += msg + "\n";
},
show: function() {
alert(log);
log = "";
}
}
})();
//运行程序
function run() {
var shop = new KFCShop();
var hamBuilder = new HamburgerBuilder();
var friesBuilder = new FrenchFriesBuilder();
//顾客通过向商店下订不同的饮食套餐,得到不同的美食
var hamburgerOrder = shop.construct(hamBuilder);
var friesOrder = shop.construct(friesBuilder);
hamburgerOrder.say();
friesOrder.say();
log.show();
}
run();
</script>
</html>
三、模式的应用
- 使用场景
- 需要生成的对象具有复杂的内部结构时。
- 相同的方法,不同的执行顺序,产生不同的结果。
- 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
2.优点
- 封装性。是客户端不必知道产品内部组成的细节。
- 建造者独立,易扩展。
- 便于控制细节风险。可以对建造过程逐步细化,而不对其他模块产生任何影响。
3.缺点
- 产品必须有共同点,范围有限制。
- 如果内部变化复杂,会有很多建造类。