设计模式重读

##单体模式(Singleton Pattern)
单体模式最简单的结构:
其作用:
1.最基本最有用的模式之一
2.划分逻辑单元, 如命名空间
其缺点:强耦合

1
2
3
4
5
6
7
var Singleton = {
attribute1: true,
attribute2: 10,
_privateAttr: null, //表面私有成员
method1: function(){},
method2: function(arg){}
};

为了解决表面私有成员实现真正私有成员单体模式更好的结构是(如下又称:模块模式[module pattern]):

1
2
3
4
5
6
7
8
var Singleton = (function(){
var privateAttribute = false;
function privateMethod = function(){}
return {
publicAttribute: true,
publicMethod: function(){}
}
})();

单体的惰性实例化(@todo 其应用场景 需要某个对象时才创建,减少内存消耗)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var Singleton = (function(){
var uniqueInstance;
function constructor(){
var privateAttribute = false;
var privateMethod = function(){};
return {
publicAttribute: true,
publicMethod: function(){}
}
}
return {
//获取实例,判断是否实例化过返回模块模式
getInstance: function(){
if(!uniqueInstance){
uniqueInstance = constructor();
}
return uniqueInstance;
}
}
})();

##工厂模式(Factory Pattern)

以下几种情景下工厂模式特别有用:
对象的构建十分复杂
需要依赖具体环境创建不同实例
处理大量具有相同属性的小对象

优点:

  1. 动态实现
  2. 节省开销

工厂模式就是不使用类或对象来来创建实例,而是通过一个子类。
为什么呢?
因为父类具有一些共有的属性但创建实例化的方法需要依赖具体环境创建不同实例。

比如, 卖车需要实例化一些具体的车类:在Vehicle.createVehicle()里不能实例化某个具体的Vehicle,因为要实例的可能是Bus,Car,Bicycle…,比较好的选择就是Bus,Car,Bicycle…这些类继承Vehicle,然后各自重写createVehicle方法去创建属于自己的实例,然后同享Vehicle的其它方法,这就是工厂模式。

在具体子类像工厂般创建实例:

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
var Vehicle = function(){};
Vehicle.prototype = {
createVehicle: function(type){
throw new Error('不支持实例化此父类');
}
sellVehicle: function(type){
var VehicleA = this.createVehicle(type);
VehicleA.assemble();
VehicleA.wash();
return VehicleA;
}
}
var Bus = function(){};
extend(Vehicle, Bus);//Bus原型继承Vehicle
Bus.prototype.createVehicle = function(type){
//根据条件创建Bus的各类型实例
if(type === '宇通'){
return bus = new BusYutong();
}
if(type === 'BYD'){
return bus = new BusBYD();
}
}

var Car = function(){};
extend(Vehicle, Car);//Car原型继承Vehicle
Car.prototype.createVehicle = function(){
//根据条件创建Car的各类型实例
}

var Bicycle = function(){};
extend(Vehicle, Bicycle);//Bicycle原型继承Vehicle
Bicycle.prototype.createVehicle = function(){
//根据条件创建Bicycle的各类型实例
}

##桥接模式
将抽象与实现隔离开来。直白一点的理解就是将调用的方法不要太依赖实际场景。
比如基于事件的方法,传入的参数尽量不要与dom或event强绑定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
不太好的处理方式:
div.addEventLister('click', getSthById);

function getSthById(e){
var id = e.target.id;
return Str[id];
}
//----------------------------------------
div.addEventLister('click', function(e){
var id = e.target.id;
getSthById(id);
});

function getSthById(id){
return Str[id];
}