参考《javascript设计模式》[美]Addy Osmani一书,下面介绍使用javascript经常会使用的主要设计模式。本博文是使用ES5语法的【下】篇,还有一个【上】篇,ES6语法会单独写个博客。
主要是以下几个设计模式:
- Constructor Pattern 构造模式
- Module Pattern 模块化模式
- Revealing Module Pattern 揭露模块化模式
- Singleton Pattern 单例模式
- Observer Pattern 观察者模式
- Mediator Pattern 中介者模式
- Prototype Pattern 原型模式
- Command Pattern 命令行模式
- Facade Pattern 外观模式
- Factory Pattern 工厂模式
- Mixin Pattern 混入模式
- Decorator Pattern 装饰者模式
- Flyweight Pattern 享元模式
所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern
6.Facade Pattern 外观模式
外观模式也是只暴露一个很简单的方法,然后该方法在内部执行,调用内部的其他方法,jquery使用了很多这种模式,如$().css、$.ajax()等1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28var module = (function() {
var _private = {
i: 5,
get: function() {
console.log("current value:" + this.i);
},
set: function(val) {
this.i = val;
},
run: function() {
console.log("running");
},
jump: function() {
console.log("jumping");
}
};
return {
facade: function(args) {
_private.set(args.val);
_private.get();
if (args.run) {
_private.run();
}
}
};
}());
// Outputs: "current value: 10" and "running"
module.facade({ run: true, val: 10 });
7.Factory Pattern 工厂模式
怎么解释呢?工厂模式就是创建一个大型的制作工厂,然后其它的对象从这个工厂中产生。1
2
3
4
5
6
7
8
9
10
11
12
13//工厂
function VehicleFactory() {}
// Our default vehicleClass is Car 默认的是Car制造工厂
VehicleFactory.prototype.vehicleClass = Car;
VehicleFactory.prototype.createVehicle = function(options) {
if (options.vehicleType === "car") {
this.vehicleClass = Car;
} else {
this.vehicleClass = Truck;
}
return new this.vehicleClass(options);
};
两个具体的工厂里面的制作空间1
2
3
4
5
6
7
8
9
10
11
12function Car(options) {
// some defaults
this.doors = options.doors || 4;
this.state = options.state || "brand new";
this.color = options.color || "silver";
}
// A constructor for defining new trucks
function Truck(options) {
this.state = options.state || "used";
this.wheelSize = options.wheelSize || "large";
this.color = options.color || "blue";
}
使用1
2
3
4
5
6
7
8var carFactory = new VehicleFactory();
var car = carFactory.createVehicle({
vehicleType: "car",
color: "yellow",
doors: 6
});
console.log(car instanceof Car);// Outputs: true
8.Mixin Pattern 混入模式
简单解释下,混入就是将一个对象的方法复制给另外一个对象。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41var Car = function(settings) {
this.model = settings.model || "no model provided";
this.color = settings.color || "no colour provided";
};
var Mixin = function() {};
Mixin.prototype = {
driveForward: function() {
console.log("drive forward");
},
driveBackward: function() {
console.log("drive backward");
},
driveSideways: function() {
console.log("drive sideways");
}
};
function augment(receivingClass, givingClass) {
if (arguments[2]) {
for (var i = 2, len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
} else {
for (var methodName in givingClass.prototype) {
if (!Object.hasOwnProperty(receivingClass.prototype, methodName)) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
// 只混入两个方法,Mixin的方法复制给Car
augment(Car, Mixin, "driveForward", "driveBackward");
// Create a new Car
var myCar = new Car({
model: "Ford Escort",
color: "blue"
});
myCar.driveForward();
myCar.driveBackward();
9.Decorator Pattern 装饰者模式
装饰模式是只针对一个基本的对象,添加一些修饰。如下面的是对MacBook,加内存(Memory函数装饰)增加75美元,雕刻(Engraving函数装饰)增加200美元,买保险(Insurance函数装饰)增加250美元。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32function MacBook() {
this.cost = function() {
return 997; };
this.screenSize = function() {
return 11.6; };
}
// Decorator 1
function Memory(macbook) {
var v = macbook.cost();
macbook.cost = function() {
return v + 75;
};
}
// Decorator 2
function Engraving(macbook) {
var v = macbook.cost();
macbook.cost = function() {
return v + 200;
};
}
// Decorator 3
function Insurance(macbook) {
var v = macbook.cost();
macbook.cost = function() {
return v + 250;
};
}
var mb = new MacBook();
Memory(mb);
Engraving(mb);
Insurance(mb);
10.Flyweight Pattern 享元模式
享元模式我感觉就是共享一些数据或者方法,有一个工厂可以管理
- Flyweight
享元对象(类似于接口),提供的可以共享的属性/方法; - Concrete Flyweight
具体享元对象,实现接口,具体实现享元对象的方法; - Flyweight Factory
享元工厂对象,创建并管理flyweight对象
实现接口的方法,由于js没有,这里我们就模拟下。1
2
3
4
5
6
7
8
9
10
11
12
13//在js模拟存虚拟的继承,类似java中的implements
Function.prototype.implementsFor = function(parentClassOrObject) {
if (parentClassOrObject.constructor === Function) {
this.prototype = new parentClassOrObject();
this.prototype.consturctor = this;
this.prototype.parent = parentClassOrObject.prototype;
}else {
//纯虚拟继承
this.prototype = parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject;
}
}
- 享元对象
1 | // Flyweight object 享元对象 |
- 具体享元对象
1 | // Implements CoffeeOrder |
- 辅助器
1 | function CoffeeOrderContext(tableNumber) { |
- 享元工厂对象
1 | //创建并管理flyweight对象 |
- 测试
1 | testFlyweight() |
所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern