ES6对抽象工厂模式与策略模式结合的实践

软件设计 2017-04-10

[blockquote]

这段代码是我在学习了java版的抽象工厂模式后,实现的ES6版抽象工厂,后期大幅修改,加入了策略模式,看起来很多逻辑看似繁琐,不必要写这么多,但是为了练习设计模式,所以才这样做。当所需的工厂种类增多后,以及需要频繁修改子工厂时,这样抽象工厂模式与策略模式的结合就会发挥巨大的优势,后期维护简单,耦合性低,便于统计子类型等。

[/blockquote]

/*   使用策略模式,来将具体的工厂类型进行封装,然后便于后期添加新的工厂,而不用修改原有的代码
*    只需要写出新的工厂类,并使用addClass方法进行添加,及可方便的得到工厂,并生产
*    可以通过对factoryList这个实例对象进行查询,即可知道有哪些工厂类型可以进行工作
*/

// 定义钢笔厂
class PenFactory{
  constructor(penColor){
    this.penColor = penColor;
  }
  produce(penNum){
    console.log(`生产了${penNum}只${this.penColor}颜色的笔`);
  }
}
//  定义纸厂
class PaperFactory{
  constructor(paperColor){
    this.paperColor = paperColor;
  }
  produce(paperNum){
    console.log(`生产了${paperNum}张${this.paperColor}颜色的纸`);
  }
}
//  定义手机厂
class PhoneFactory{
  constructor(weight){
    this.weight = weight;
  }
  produce(num){
    console.log(`生产了${num}个${this.weight}重的手机`);
  }
}


//  定义工厂列表类,实现抽象工厂模式,以及策略模式结合使用
class FactoryList{
  constructor(){
    //  用于保存不同的策略名称,及对应的方案
    this.strateges = {};
  }
  addClass(factoryClass){
    //  new 后要跟真正的类不能是类名的字符串,这里接收的参数是真正的类,使用它的name属性获取类名
    this.strateges[factoryClass.name] = function(config){return new factoryClass(config)};
  }
  getFactory(className,config){
    return this.strateges[className].call(null,config);
  }
}
var factoryList = new FactoryList();

factoryList.addClass(PhoneFactory); // 这里的Phone是真正的类,不是字符串类名
factoryList.addClass(PenFactory);
factoryList.addClass(PaperFactory);


// NOTE: 这里定义我自己的工厂,由我决定生存哪些产品,以及有什么工厂
var myFactory = {};
var phoneF = factoryList.getFactory('PhoneFactory','500g');
var penF = factoryList.getFactory('PenFactory','红色');
var paperF = factoryList.getFactory('PaperFactory','A4');
//  这里要绑定那个具体的工厂类,借用this,确保我自己的厂子的某类具体的生产参数不出错
myFactory.producePhone = phoneF.produce.bind(phoneF);
myFactory.producePen = penF.produce.bind(penF);
myFactory.producePaper = paperF.produce.bind(paperF);
myFactory.producePhone(10);  //  生产了10个500g重的手机
myFactory.producePen(20);    //  生产了20只红色颜色的笔
myFactory.producePaper(30);  //  生产了30张A4颜色的纸

相关推荐

82602411 / 0评论 2016-09-23