JavaScript模式读书笔记 第7章 设计模式

1,单例模式
    -1,最简单的单例:
     
<script>
//obj为单例
var obj = {
myProp: "My Value"
};
var obj1 = obj;
var obj2 = obj;
console.log(obj1 == obj2);//true
console.log(obj1 === obj2);//true
  </script>
-2,静态属性中的实例:
    
 <script>
function Universe(){
if(typeof Universe.instance === "object"){
return Universe.instance;
}
 
this.start_time = 0;
this.bang = "Big";
 
Universe.instance = this;
}
 
var u1 = new Universe();
var u2 = new Universe();
console.log(u1 === u2);//true
  </script>
    缺点:Universe.instance是公开的属性,其他代码可能无意更改此属性.
-3,闭包中的实例
    
  <script>
function Universe(){
//缓存私有变量
var instance = this;
 
this.start_time = 0;
this.bang = "Big";
//重写构造函数,返回私有变量
Universe = function(){
return instance;
};
}
var u1 = new Universe();
var u2 = new Universe();
console.log(u1 === u2);//true
  </script>
上述代码在第一次调用的时候返回this,在第二次、第三次调用的时候,将会重写构造函数,该重写构造函数通过闭包访问了私有的instance属性,并且只是简单返回该Instance。见如下代码:
    
 
  <script>
function Universe(){
//缓存私有变量
var instance = this;
 
this.start_time = 0;
this.bang = "Big";
//重写构造函数,返回私有变量
Universe = function(){
return instance;
};
}
Universe.prototype.nothing = true;
var u1 = new Universe();
Universe.prototype.everything = true;
     var u2 = new Universe();
 
 
console.log(u1.nothing);//true
console.log(u2.nothing);//true
     console.log(u1.everything);//undefined
console.log(u2.everything);//undefined
  </script>
因为u1的constructor指向了原始的构造函数,而不是重新定义的构造函数。(这块还是没搞明白。。。。。。只是觉得好神奇)
 下面的例子,在构造函数重新定义了对应的constructor。
       
 function Universe(){
//缓存私有变量
var instance ;
 
//重写构造函数,返回私有变量
Universe = function  Universe(){
return instance;
};
//保留原属性
Universe.prototype = this;
//创建实例 
instance = new Universe();
//重置构造函数指针
instance.constructor = Universe;
 
 
this.start_time = 0;
this.bang = "Big";
 
return instance;
}
Universe.prototype.nothing = true;
var u1 = new Universe();
Universe.prototype.everything = true;
     var u2 = new Universe();
 
 
console.log(u1.nothing);//true
console.log(u2.nothing);//true
     console.log(u1.everything);//true
console.log(u2.everything);//true
  </script>
2,工厂模式
    设计工厂模式是为了创建对象,它通常在类或者类的静态方法中实现,具有下列目标:
        a. 当创建相似对象时执行重复操作。
        b.在编译时不知道具体类型的时候,为工厂客户提供一种创建对象的接口。
 
<script>
function CarMaker(){
CarMaker.prototype.drive = function(){
return "Vroom, I hava " + this.doors + " doors";
};
 
//静态工厂方法 
CarMaker.factory = function(type){
var constr = type, newCar;
 
if(typeof CarMaker[constr] !== "function"){
throw{
name: "Error",
message: constr + " doesn't exist";
};
}
//工厂方法
if(typeof CarMaker[constr].prototype.drive !== "function"){
CarMaker[constr].prototype = new CarMaker();
}
newCar = new CarMaker[constr]();
return newCar;
};
 
CarMaker.compact = function(){
this.doors = 4;
};
CarMaker.convertible = function(){
this.doors = 2;
};
 
CarMaker.SUN = function(){
this.doors = 24;
};
}
  </script>
内置工厂模式:
     
<script>
var o = new Object(),
n = new Object(1),
s = Object('1'),
b = Object(true);
 
console.log(o.constructor === Object);//true
console.log(n.constructor === Number);//true
console.log(s.constructor === String);//true
console.log(b.constructor === Boolean);//true
  </script>
3,迭代器模式
    遍历复杂数据结构,具体调用格式类似java集合类。
<script>
var element;
while(element = agg.next){
//业务处理
console.log(element);
}
  </script>
    
 <script>
var agg = (function(){
var index = 0, 
data = [1, 2, 3, 4, 5],
length = data.length;
return {
next: function(){
var element;
if(!this.hasNext()){
return null;
}
element = data[index];
index = index + 1;
return element;
},
hasNext: function(){
return index < length;
},
rewind: function(){
index = 0;
},
current: function(){
return data[index];
}
};
}());
agg.rewind();
console.log(agg.current());//1
while(agg.hasNext()){
console.log(agg.next());// 1 2 3 4 5
}
  </script>

4,装饰者模式
    装饰者模式,可以在运行时动态添加附加内容到对象中。装饰者模式可以从仅具有基本功能的普通对象开始,然后从可用装饰资源池中选择需要用于增强普通对象的那些功能,并且安装顺序进行装饰,尤其是当装饰顺序很重要的时候。
    例如如下场景,根据固定的商品价格a,我们可以组合不同的税收,最后得出不同的最终价格。
    
  <script>
var sale = new Sale(100);
sale = sale.decorator("fedtax");//增加联邦税
sale = sale.decorator("quebec");//增加省税
sale = sale.decorator("money");//以美元形式展示
sale.getPrice();//"$112.88"
 
//使用不同的税收策略
var sale = new Sale(100);
sale = sale.decorator("fedtax");//增加联邦税
sale = sale.decorator("cdn");//以cdn形式展示
sale.getPrice();//"CDN$ 105.88"
  </script>
    
<script>
function Sale(price){
this.price = price || 100;
}
Sale.prototype.getPrice = function(){
return this.price;
};
//装饰者对象
Sale.decorators = {};
 
//装饰者从父对象获取值,然后再修改该值
Sale.decorators.fedtax = {
getPrice: function(){
var price = this.uber.getPrice();
price += price * 0.005;
return price;
}
};
Sale.decorators.quebec = {
getPrice: function(){
var price = this.uber.getPrice();
price += price * 0.075;
return price;
}
};
Sale.decorators.money = {
getPrice: function(){
return "$" + this.uber.getPrice().toFixed(2);
}
};
Sale.decorators.cdn = {
getPrice: function(){
return "CDN$" + this.uber.getPrice().toFixed(2);
}
};
 
Sale.prototype.decorator = function(decorator){
var F = function(){},
overrides = this.constructor.decorators[decorator],
i, newobj;
F.prototype = this;
 
newobj = new F();
newobj.uber = F.prototype;
for(i in overrides){
if(overrides.hasOwnProperty(i)){
newobj[i] = overrides[i];
}
}
return newobj;
};
 
var sale = new Sale(100);
sale = sale.decorator("fedtax");//增加联邦税
sale = sale.decorator("quebec");//增加省税
sale = sale.decorator("money");//以美元形式展示
console.log(sale.getPrice());//"$112.88"
 
//使用不同的税收策略
var sale = new Sale(100);
sale = sale.decorator("fedtax");//增加联邦税
sale = sale.decorator("cdn");//以cdn形式展示
console.log(sale.getPrice());//"CDN$ 105.88"
  </script>

5,策略模式
















posted @ 2014-12-09 17:53  梅尔加德斯  阅读(248)  评论(0编辑  收藏  举报