javascript工厂模式

简单工厂

单纯使用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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值