javascript工厂模式

来源:互联网 发布:漫画美图软件 编辑:程序博客网 时间:2024/05/11 18:53

简单工厂

单纯使用new会导致两个类之间的依赖性,当有多个类构造时,使用一个方法来实例化哪个具体的类,如下面的Fruit水果商店类,通过一个简单的switch层来判断。

   var FruitShop = function(){};   FruitShop.prototype = {       showFruit: function(model){           var fruit;           switch(model){               case 'Apple':                   fruit = new Apple();                   break;               case 'Banana':                   fruit = new Banana();                   break;               default:                   fruit = new Pear();           }           Interface.check(fruit, FruitShop);           //实现了FruitShop接口           fruit.wash();           fruit.sell();           return fruit;       }   }

各种水果之间可以互换使用,因为它们实现了接口FruitShop,因此拥有了水果的wash和sell方法,有关Interface类和check函数可以参考另一篇js中的接口,如果不实现相同接口,工厂模式所谓的批量生产类似对象的作用就失效了。
如果想增加一类水果怎么办,还要修改Fruit类,然而Fruit类的功能并没有修改,这样的话我们考虑把创建新实例的逻辑再分离出来,以后想增加水果修改FruitFactory类就可以

   var FruitFactory = {      createFruit: function(model){          var fruit;          switch(...)          return fruit;      }   }   var FruitShop = function(){};   FruitShop.prototype = {       showFruit: function(model){           var fruit = FruitFactory.createFruit(model);           fruit.wash();           fruit.sell();           return fruit;       }   }

真正的工厂模式

现在我们想让每种水果决定从哪一类公司进货

   var FruitShop = function(){}'   FruitShop.prototype = {       showFruit: function(model){           var fruit = this.createFruit(model);           fruit.wash();           fruit.sell();           return fruit;       },       createFruit: function(model){           throw new Error('Unsupported operation on a abstract class');       }   }

Fruit现在是一个抽象类,它不能被实例化,设计一个特定的水果类需要扩展Fruit,重定义其中的createFruit方法。关于extend方法可以参考我另一篇js中的extend方法

    var Ashop = function(){};    extend(Ashop, FruitShop);    Ashop.prototype.createFruit = function(model){        var fruit;        switch(model){          case 'Apple':               fruit = new Apple();               break;           case 'Banana':               fruit = new Banana();               break;           default:               fruit = new Pear();       }       Interface.check(fruit, Fruit);       //实现了Fruit接口       fruit.wash();       fruit.sell();       return fruit;    }    var Bshop = function(){};    extend(Bshop, FruitShop);    Bshop.prototype.createFruit = function(model){        ...    }

这些工厂方法生成的对象都实现了FruitShop接口,所以在其他代码眼中可以互换,现在的水果可以是Ashop或者Bshop中进货的:

    var shop1 = new Ashop();    var apple = shop1.showFruit('Apple');    var shop2 = new Bshop();    var apple = shop2.showFruit('Apple');   

我们可以对每个子类进行修改,以支持相关厂家的不同水果,这是工厂模式最重要的特点。对fruit一般性的操作逻辑放在父类fruitShop中,而具体的fruit对象实例化则留在子类中,一般性的代码集中在父类,而有变化的代码封装在子类中。

总结

如果需要像水果一样,有多种需要实现同一接口的对象,这时我们就需要使用工厂模式对new对象的过程进行一些逻辑分析和封装

0 0
原创粉丝点击