平常来说,建立对象的时刻我们都习气运用new
关键字来挪用constructor构造函数,但运用这类体式格局会有一些瑕玷,起首构造器函数的建立自身就是为了模拟其他一些面向对象言语的特征,有些人以为这是non-sense;另一方面,在一个类顶用new
关键字挪用其他类的构造函数,会形成两个类之间的耦合,设想形式应当要只管防止这些影响代码可重用性的题目。
简朴工场形式
一个工场可以临盆统一类的多种物品,详细临盆哪一种就看客户下什么定单了。工场形式也是一样,我们建立一个工场类,它可以建立多种实例,由开发者指定。
假设有一个临盆交通工具的工场类Vehicle
,它包括天生多种交通工具实例的要领。
function Vehicle() {}
Vehicle.prototype = {
createVihicle: function(options) {
var vehicle;
switch(options.type) {
case 'car':
vehicle = new Car();
break;
case 'truck':
vehicle = new Truck();
break;
default:
vehicle = new Bike();
}
return vehicle;
}
};
在运用这个类临盆对象的时刻,传入option
参数,在参数中的type
属性划定我们须要的范例,构造函数就可以返回我们须要的对象范例了。运用这类要领,假如我们要增添新的交通工具范例也是很轻易的,在工场的switch
中直接增添一个case
就可以了。
switch(options.type) {
case 'car':
vehicle = new Car();
break;
case 'truck':
vehicle = new Truck();
break;
case 'plane':
vehicle = new Plane();
break;
default:
vehicle = new Bike();
}
经由历程这类体式格局,将成员对象的建立事情转交给外部对象,可以像上述代码一样转交给自力的定名空间,像Car
,Truck
,Plane
等,假如外部对象属于统一类的话,将它们构造为一个大类中的子类比较合理。
工场形式
以上引见的是简朴工场形式,简朴工场形式会把建立事情交给外部的类来做,这现实上会增添类的数目,并不利于代码的构造。真正的工场形式会把建立事情交给子类来完成,父类只对建立历程当中的平常性题目举行处置惩罚,这些处置惩罚会影响到每一个子类,而子类之间互相自力,可以对建立历程举行一些定制化操纵。
还是以临盆交通工具为例,将交通工具父类改写为一个抽象类,它不担任直接临盆交通工具,而是经由历程它派生出一些子类,这些子类代表差别的国度,差别的国度可以临盆本身的交通工具。
将父类抽象化:
function Vehicle() {}
Vehicle.prototype = {
createVihicle: function(options) {
// 这里不直接临盆,假如直接挪用会抛出毛病
throw new Error('Unsupported operation on an abstract class.')
}
};
差别的国度作为子类,子类起首对父类举行继续,然后完成本身的createVehicle
要领。
function China() {}
// 继续要领
extend(China, Vehicle);
// 完成本身的createVehicle要领
China.prototype.createVehicle = function(options) {
var vehicle;
switch(options.type) {
case 'car':
vehicle = new Car();
break;
case 'truck':
vehicle = new Truck();
break;
default:
vehicle = new Bike();
}
return vehicle;
}
今后要临盆交通工具的时刻就挪用China
子类的createVehicle
要领就可以了。
var chinaVehicle = new China();
var myCar = chinaVehicle.createVehicle({ type: 'Car' });
平常性的代码集合在父类中,个性化的代码在子类中零丁定制。
工场形式实用场所
子类的共同点是它们都完成了统一批接口,只管内部细节并不尽相同。临盆对象的要领有一个挑选性的历程,这类挑选可所以开发者自定的,比方须要临盆何种交通工具,也可所以自动挑选的,比方依据浏览器环境临盆适宜的XHR对象。关于相似性很高,完成了统一类接口的对象,工场形式是比较适宜的。
别的的一大优点就是子类的一些设置代码可以悉数放在父类的构造器函数中,不须要在每一个子类的构造函数中反复运转一样的代码,只须要在父类的代码中完成一次就好。子类只须要专注于完成本身的要领,不必斟酌别的题目。
末了一点则是假如一个类中包括了许多更小的子类作为本身的组成部分,那末替代这些子类的事情会很简朴,由于工场形式降低了模块之间的耦合度,一个模块并不会依赖于其某一组成部分。