1 什么是工厂模式?
工厂模式是用来创建对象的一种最常用的设计模式。我们不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。工厂模式根据抽象程度的不同可以分为:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
1-1 简单工厂模式
简单工厂模式,又叫静态工厂方法,由一个工厂对象来决定创建某一种产品对象类的实例,主要用来创建同一类对象。
var basketball = function(){ this.title = '篮球'; } basketball.prototype = { getMenberNum :function(){ console.log('5个人'); }, getPlayAction:function(){ console.log('投篮') } } var football = function(){ this.title = '足球'; } football.prototype = { getMenberNum :function(){ console.log('11个人'); }, getPlayAction:function(){ console.log('射门') } } var factory = function(type){ switch(type){ case 'basketball': return new basketball(); case 'football': return new football(); } } //然后我们就可以这么用 oPlay = factory('basketball'); oPlay.getMenber(); oPlay2 = factory('football'); oPlay2.getPlayAction();
如果两个类的共有属性比较多的时候,我们可以这样用
var factory = function(name,age,sex,national){ var obj = {}; obj.name = name; obj.age = age; obj.sex = sex; switch(national){ case 'Chinese': obj.speak = function(){ console.log('Speak Chinese'); }; break; case 'England': obj.speak = function(){ console.log('SpeakEnglish') }; break; } return obj; } var person = new factory("Jack",'15','Man',"Chinese"); person.speak();
简单工厂的优点在于,你只需要一个正确的参数,就可以获取到你所需要的对象,而无需知道其创建的具体细节。但是在函数内包含了所有对象的创建逻辑(构造函数)和判断逻辑的代码,每增加新的构造函数还需要修改判断逻辑代码。当我们的对象不是上面的3个而是30个或更多时,这个函数会成为一个庞大的超级函数,便得难以维护。所以,简单工厂只能作用于创建的对象数量较少,对象的创建逻辑不复杂时使用。
1-2 工厂方法模式
工厂方法模式,通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例。
var Court = function (type, content) { if (this instanceof Court) { return new this[type](content); } else { return new Court(type, content); } } Court.prototype = { basketball : function (content) { this.content = content; (function (content) { console.log(content + 'basketball'); })(content); }, football : function (content) { this.content = content; (function (content) { console.log(content + 'football'); })(content); } } var data = [{ type: 'basketball', content: '5人打' }, { type: 'football', content: '11人踢' } ]; for (var i = 0; i < data.length; i++) { Court(data[i].type, data[i].content); }
// 5人打basketball
// 11人踢football
对于创建多类对象,简单工厂就不太实用了。
通过工厂方法模式可以轻松的创建多个类的实例对象,而且创建对象的方式避免了使用者与对象类之间的耦合,用户不必关心创建该对象的具体类,只需调用工厂方法即可。
1-3 抽象工厂模式
抽象工厂模式,通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。
/*定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家去实现*/ var AbsProducer = function(){}; AbsProducer.prototype = { sell:function(name){ var product = this.create(model); product.showName(); return product; }, create:function(name){ throw new Error("抽象类不支持该操作"); } }
联想工厂:LenovoFactory.js
var LenovoFactory = function () {}; extend(LenovoFactory, AbsProducer); LenovoFactory.prototype.create = function (name) { var product; switch (name) { case "phone": product = new LenovoPhone(); break; case "computer": product = new LenovoComputer(); break; } Interface.ensureImplements(product, ElectronicProduct); product.showName(); return product; } function LenovoPhone() {}; LenovoPhone.prototype = { showName: function () { console.log("我是联想厂商生产的手机,取名为Lenovo-phone"); }, showCpu: function () { console.log("联想手机cpu一般般咯"); }, showSysType: function () { console.log("姑且认为联想手机系统为WP吧"); } }; function LenovoComputer() {}; LenovoComputer.prototype = { showName: function () { console.log("我是联想厂商生产的电脑,型号为Y系列"); }, showCpu: function () { console.log("联想电脑cpu,四代I7处理器"); }, showSysType: function () { console.log("联想电脑系统为正版win7"); } };
苹果工厂:AppleFactory.js
var AppleFactory = function () {}; extend(AppleFactory, AbsProducer); AppleFactory.prototype.create = function (name) { var product; switch (name) { case "phone": product = new Iphone(); break; case "computer": product = new Mac(); break; } Interface.ensureImplements(product, ElectronicProduct); product.showName(); return product; }; function Iphone() {}; Iphone.prototype = { showName: function () { console.log("我是苹果公司生产的手机,取名为Iphone"); }, showCpu: function () { console.log("iphone手机CPU是基于ARM架构重新设计的"); }, showSysType: function () { console.log("iphone系统为IOS9"); } }; function Mac() {}; Mac.prototype = { showName: function () { console.log("我是苹果公司生产的电脑,取名为Mac"); }, showCpu: function () { console.log("mac cpu还不错吧"); }, showSysType: function () { console.log("mac系统为OS X"); } };
调用:
/*定义了一个ElectronicProduct电子产品的接口,该接口有以下几个名称*/ var ElectronicProduct = new Interface("ElectronicProduct",["showName", "showCpu", "showSysType"]); //这里你想要哪个品牌的电子产品,直接new一个该品牌的工厂即可。 var factory = new AppleFactory(); var product = factory.create("phone"); product.showSysType(); product.showCpu();
抽象工厂其实是一个实现子类继承父类的方法,在这个方法种我我们需要传入子类以及要继承父类的名称.
过渡类的原型继承,不是继承父类的原型,而是通过new 复制一个父类的实例,过渡类不仅仅继承了父类的原型方法,还继承了父类的对象属性.