设计模式之工厂方法

工厂方法模式是简单工厂模式的延申,他继承了简单工厂模式的优势,同时还弥补了简单工厂模式的缺陷,更好的符合开闭原则的要求,在增长新的具体产品对象时不须要对已有的系统作任何的修改。设计模式

什么是工厂方法

工厂方法模式简称为工厂模式,又可称做虚拟构造器模式或多态工厂模式。工厂方法模式是种类建立型模式。在工厂方法模式中,工厂父类负责定义建立产品对象的公共接口,而工厂子类负责生成具体的产品对象,这样作的目的是将产品类的实例操做延迟到工厂子类中完成,即经过工厂子类来肯定究竟应该实例化哪个具体产品类。框架

工厂方法模式是一种建立型设计模式,其在父类中提供一个建立对象的方法,容许子类决定实例化对象的类型。函数

工厂方法模式建议使用特殊的工厂方法代替对于对象构造函数的直接调用,对象仍将经过new运算符建立, 只是该运算符改在工厂方法中调用罢了。 工厂方法返回的对象一般被称做”产品“。spa

工厂方法优缺点

工厂方法模式是使用频率最高的设计模式之一,是不少开源框架和API类库的核心模式。做为一种建立类模式,在任何须要生成复杂对象的地方,均可以使用工厂方法模式。有一点须要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只须要经过new就能够完成建立的对象,无需使用工厂模式。若是使用工厂模式,就须要引入一个工厂类,会增长系统的复杂度。设计

优势
  1. 只须要关心产品对应的工厂
  2. 添加新产品是只要添加一个具体工厂和具体产品
  3. 可扩展性很是好,彻底符合开闭原则
缺点
  1. 类个数成倍的增长
  2. 抽象层进行定义,增长了系统的抽象性和理解难度

示例

工厂方法主要包含4个类,分别是:code

  1. 产品类
  2. 具体产品类
  3. 建立者类
  4. 具体建立者类

产品类主要为工厂方法提供抽象的方法具体方法由产品内部实现,然而建立者类(抽象工厂)也是同理主要负责提供建立方法具体由具体建立者类(工厂方法)内部实现。对象

类图以下所示:blog

image

代码示例继承

// 抽象产品接口(产品类)
interface Product2{
    method1() : void;
    method2() : void;
}
// 具体产品一(具体产品类)
class ConcreteProduct_1 implements Product2 {
    constructor(){}
    method1() {
        //  具体业务代码
    }
    method2() {
        //  具体业务代码
    }
}
// 具体产品二(具体产品类)
class ConcreteProduct_2 implements Product2 {
    constructor(){}
    method1() {
        //  具体业务代码
    }
    method2() {
        //  具体业务代码
    }
}
// 抽象工厂(建立者类)
abstract class Creator {
    public abstract createProduct(type : number) : Product;
}
// 具体工厂(具体建立者类)
class ConcreteCreator extends Creator {
    constructor(){
        super();
    }
    public createProduct(type : number) : Product {
        let product = null;
        if (type === 1) {
            product = new ConcreteProduct_1();
        } else if (type === 2) {
            product = new ConcreteProduct_2();
        }
        return product;
    }
}
// 使用
const creator:Creator = new ConcreteCreator();
const myProduct:Product = creator.createProduct(1);

总结

若是你但愿复用现有对象来节省系统资源,而不是每次都从新建立对象,可以使用工厂方法。在处理大型资源密集型对象时,你会常常碰到这种资源需求。在抽象工厂中能够声明多个抽象的工厂方法,在具体工厂中实现了这些工厂方法,这些方法能够包含不一样的业务逻辑,以知足产品对象的多样化建立需求。接口

在工厂类中能够直接调用产品类的业务方法,客户端无须调用工厂方法建立产品对象,直接使用工厂对象便可调用所建立的产品对象中的业务方法,实现对工厂方法的隐藏。