设计模式-----工厂方法模式

工厂方法模式

前言

在前面博主写的文章:设计模式-----简单工厂模式,发现简单工厂模式存在一系列问题:html

  • 工厂类集中了全部实例(产品)的建立逻辑,一旦这个工厂不能正常工做,整个系统都会受到影响
  • 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会形成工厂逻辑过于复杂
  • 简单工厂模式因为使用了静态工厂方法,静态方法不能被继承和重写,会形成工厂角色没法造成基于继承的等级结构

为了解决上述的问题,咱们又使用了一种新的设计模式:工厂方法模式java

1.介绍

1.1 定义

工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,经过定义工厂父类负责定义建立对象的公共接口,而子类则负责生成具体的对象数据库

1.2 主要做用

将类的实例化(具体产品的建立)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(建立)哪个类设计模式

1.3 解决的问题

工厂一旦须要生产新产品就须要修改工厂类的方法逻辑,违背了“开放 - 关闭原则ide

  1. 即简单工厂模式的缺点
  2. 之因此能够解决简单工厂的问题,是由于工厂方法模式把具体产品的建立推迟到工厂类的子类(具体工厂)中,此时工厂类再也不负责全部产品的建立,而只是给出具体工厂必须实现的接口,这样工厂方法模式在添加新产品的时候就不修改工厂类逻辑而是添加新的工厂子类,符合开放封闭原则,克服了简单工厂模式中缺点

2.模式原理

2.1 UML类图

2.2 模式组成

组成(角色) 关系 做用
抽象产品(Product) 具体产品的父类 描述具体产品的公共接口
具体产品(Concrete Product) 抽象产品的子类;工厂类建立的目标类 描述生产的具体产品
抽象工厂(Creator) 具体工厂的父类 描述具体工厂的公共接口
具体工厂(Concrete Creator) 抽象工厂的子类;被外界调用 描述具体工厂;实现FactoryMethod工厂方法建立产品的实例

2.3 使用步骤

  1. 建立抽象工厂类,定义具体工厂的公共接口
  2. 建立抽象产品类 ,定义具体产品的公共接口
  3. 建立具体产品类(继承抽象产品类) & 定义生产的具体产品
  4. 建立具体工厂类(继承抽象工厂类),定义建立对应具体产品实例的方法
  5. 外界经过调用具体工厂类的方法,从而建立不一样具体产品类的实例

3.实例讲解

3.1 实例概况

  • 背景:小成有一间塑料加工厂(仅生产A类产品);随着客户需求的变化,客户须要生产B类产品
  • 冲突:改变原有塑料加工厂的配置和变化很是困难,假设下一次客户须要再发生变化,再次改变将增大很是大的成本
  • 解决方案:小成决定置办塑料分厂B来生产B类产品

3.2 使用步骤

3.2.1:建立抽象工厂类,定义具体工厂的公共接口

abstract class Factory{
    public abstract Product Manufacture();
}

3.2.2 建立抽象产品类 ,定义具体产品的公共接口

abstract class Product{
    public abstract void Show();
}

3.2.3 建立具体产品类(继承抽象产品类), 定义生产的具体产品

//具体产品A类
class  ProductA extends  Product{
    @Override
    public void Show() {
        System.out.println("生产出了产品A");
    }
}

//具体产品B类
class  ProductB extends  Product{

    @Override
    public void Show() {
        System.out.println("生产出了产品B");
    }
}

3.2.4 建立具体工厂类(继承抽象工厂类),定义建立对应具体产品实例的方法

//工厂A类 - 生产A类产品
class  FactoryA extends Factory{
    @Override
    public Product Manufacture() {
        return new ProductA();
    }
}

//工厂B类 - 生产B类产品
class  FactoryB extends Factory{
    @Override
    public Product Manufacture() {
        return new ProductB();
    }
}

3.2.5 外界经过调用具体工厂类的方法,从而建立不一样*具体产品类的实例

//生产工做流程
public class FactoryPattern {
    public static void main(String[] args){
        //客户要产品A
        FactoryA mFactoryA = new FactoryA();
        mFactoryA.Manufacture().Show();

        //客户要产品B
        FactoryB mFactoryB = new FactoryB();
        mFactoryB.Manufacture().Show();
    }
}

结果:

生产出了产品A
生产出了产品B

4.优势

  • 更符合开-闭原则
    新增一种产品时,只须要增长相应的具体产品类和相应的工厂子类便可

简单工厂模式须要修改工厂类的判断逻辑ui

  • 符合单一职责原则
    每一个具体工厂类只负责建立对应的产品

简单工厂中的工厂类存在复杂的switch逻辑判断设计

  • 不使用静态工厂方法,能够造成基于继承的等级结构

简单工厂模式的工厂类使用静态工厂方法code

总结htm

工厂模式能够说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优势的同时,让扩展变得简单,让继承变得可行,增长了多态性的体现对象

5.缺点

  • 添加新产品时,除了增长新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增长,在必定程度上增长了系统的复杂度;同时,有更多的类须要编译和运行,会给系统带来一些额外的开销
  • 因为考虑到系统的可扩展性,须要引入抽象层,在客户端代码中均使用抽象层进行定义,增长了系统的抽象性和理解难度,且在实现时可能须要用到DOM、反射等技术,增长了系统的实现难度
  • 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,若是要更换另一种产品,仍然须要修改实例化的具体工厂类

  • 一个具体工厂只能建立一种具体产品

6.应用场景

  • 当一个类不知道它所须要的对象的类时
    在工厂方法模式中,客户端不须要知道具体产品类的类名,只须要知道所对应的工厂便可
  • 当一个类但愿经过其子类来指定建立对象时
    在工厂方法模式中,对于抽象工厂类只须要提供一个建立产品的接口,而由其子类来肯定具体要建立的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展
  • 将建立对象的任务委托给多个工厂子类中的某一个,客户端在使用时能够无须关心是哪个工厂子类建立产品子类,须要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中
相关文章
相关标签/搜索