软件设计 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颜色的纸