25. 设计模式

一、工厂模式

使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体。工厂模式是抽象了创建具体对象的过程。ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节。

<xmp>
function person1(){
    var o = new Object();
    o.name = "Nicholas";
    o.age = 29;
    o.job = "Software Engineer";
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
function person2(){
    var o = new Object();
    o.name = "Greg";
    o.age = 27;
    o.job = "Doctor";
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
</xmp>

用工厂模式可写成如下:

<xmp>
function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
</xmp>

什么时候使用工厂模式:
1 对象的构建十分复杂
2 需要依赖具体环境创建不同实例
3 处理大量具有相同属性的小对象
不要滥用工厂模式
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

二、构造函数模式

在讲解构造函数模式之前,我们先来看一个例子:

<xmp>
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
</xmp>

和工厂模式对比,构造函数有几个不同的地方:
1.没有显式地创建对象;
2.直接将属性和方法赋给了 this 对象;
3.没有 return 语句;
4.创建 Person 的新实例,必须使用 new 操作符。
5.构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。

构造函数的缺点:
每个方法都要在每个实例上重新创建一遍。

三、原型模式

我们创建的每个函数都有一个 prototype (原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

<xmp>
function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
</xmp>

四、寄生构造函数模式

寄生构造函数模式是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

<xmp>
function Person(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
</xmp>

注:返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖 instanceof 操作符来确定对象类型。

评论

0 条评论