工厂模式:是一种实现“工厂”概念的面上对象设计模式。实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中。创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象。工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题,由子类实现这个方法来创建具体类型的对象。
1.简单工厂:
//定义接口 var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride', 'repair']); //单体(返回实现了Bicycle接口的对象) var BicycleFactory = { createBicycle: function(model) { var bicycle; switch(model){ case 'The Speedster': bicycle = new Speedster(); break; case 'The Lowrider': bicycle = new Lowrider(); break; case 'The Comfort Cuiser': default: bicycle = new ComfortCruiser(); } Interface.ensureImplements(bicycle, Bicycle); return bicycle; } }; //Speedster类 var Speedster = function() { //..... //继承Bicycle接口 }; Speedster.prototype = { assemble: function() { console.log("组装汽车Speedster") }, wash: function() { console.log("清洗汽车Speedster") }, ride: function() { }, repair: function() { } }; var BicycleShop = function() {}; BicycleShop.prototype = { sellBicycle: function(model) { var bicycle = BicycleFactory.createBicycle(model); bicycle.assemble(); bicycle.wash(); return bicycle; } }; var californiaCruiser = new BicycleShop(); var yourNewBike = californiaCruiser.sellBicycle('The Speedster');
2.工厂模式:
//----------工厂模式:----------- var BicycleShop = function(){} BicycleShop.prototype={ sellBicycle: function( model ){ var bicycle = this.createBicycle( model ); return bicycle; }, createBicycle: function( model ){ throw new Error( " Unsupported " ); } } var AcmeBicycleShop = function(){}; extend( AcmeBicycleShop , BicycleShop ); AcmeBicycleShop.prototype.createBicycle = function( model ){ var bicycle; switch( model ){ case "The Speedster": bicycle = new AcmeSpeedster(); break; case "The Lowrider": bicycle = new AcmeLowrider(); break; case "The Cruiser": default: bicycle = new AcmeCruiser(); break; } return bicycle; } var GeneralBicycleShop = function(){}; extend( GeneralBicycleShop , BicycleShop ); GeneralBicycleShop.prototype.createBicycle = function( model ){ ... }
var acmeShop = new AcmeBicycleShop(); var newBicycle = acmeShop.sellBicycle("The Speedster");
下面借鉴别人的博客:
假如我们想在网页面里插入一些元素,而这些元素类型不固定,可能是图片,也有可能是连接,甚至可能是文本,根据工厂模式的定义,我们需要定义工厂类和相应的子类,我们先来定义子类的具体实现(也就是子函数):
var page = page || {}; page.dom = page.dom || {}; //子函数1:处理文本 page.dom.Text = function () { this.insert = function (where) { var txt = document.createTextNode(this.url); where.appendChild(txt); }; }; //子函数2:处理链接 page.dom.Link = function () { this.insert = function (where) { var link = document.createElement('a'); link.href = this.url; link.appendChild(document.createTextNode(this.url)); where.appendChild(link); }; }; //子函数3:处理图片 page.dom.Image = function () { this.insert = function (where) { var im = document.createElement('img'); im.src = this.url; where.appendChild(im); }; };
那么我们如何定义工厂处理函数呢?其实很简单:
page.dom.factory = function (type) { return new page.dom[type]; }
使用方式如下:
var o = page.dom.factory('Link'); o.url = 'http://www.cnblogs.com'; o.insert(document.body);
什么时候使用工厂模式
以下几种情景下工厂模式特别有用:
- 对象的构建十分复杂
- 需要依赖具体环境创建不同实例
- 处理大量具有相同属性的小对象
什么时候不该用工厂模式
不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。