FactoryMethodPattern工厂方法模式

工厂方法模式

1.定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

基本工厂方法模式

抽象产品类

public abstract class AbstractProduct {
    // 公共方法
    public void methodOne() {
        // 业务逻辑
    }

    // 抽象方法
    public abstract void methodTwo();
}

具体产品类,都继承自抽象产品类

public class ConcreteProductOne extends AbstractProduct {
    public void methodTwo() {
      // 业务逻辑
    }
}

public class ConcreteProductTwo extends AbstractProduct {
  public void methodTwo() {
      // 业务逻辑
    }
}

抽象工厂类,负责定义产品对象的产生

public abstract class AbstractProductFactory {
    // 创建一个产品对象,参数类型通常为 String, Enum, Class
    public abstract <T extends AbstractProduct> T createProduct(Class<T> c);
}

具体工厂类,继承抽象工厂类

public class ProductFactory extends AbstractProductFactory {
    // 创建一个产品对象,参数类型通常为 String, Enum, Class
    public <T extends AbstractProduct> T createProduct(Class<T> c) {
        AbstractProduct abstractProduct = null;

        try {
            abstractProduct = (AbstractProduct) Class.forName(c.getName()).newInstance();
        } catch (Exception exception) {
            // 异常处理
        }

        return abstractProduct;
    }
}

场景类

public class Client {
    public static void main(String[] args) {
      AbstractProductFactory productFactory = new ProductFactory();

      AbstractProduct productOne = productFactory.createProduct(ConcreteProductOne.class);
      AbstractProduct productTwo = productFactory.createProduct(ConcreteProductTwo.class);

        // TODO
    }
}

2.应用

2.1 优点

  • 良好的封装性,代码结构清晰,一个对象的创建具有条件的约束
  • 扩展性非常优秀,在增加产品的情况下,只适当修改工厂类或扩展一个工厂类
  • 屏蔽产品类,调用者不需要关心产品类如何变化,只需要关注产品接口保持不变
  • 工厂方法模式是典型的解耦框架。高层模块只需要知道产品抽象类,不用关心其它实现类

2.2 使用场景

  • 工厂方法模式是new一个对象的替代品,在所有需要生成对象的地方都可以使用,,但需要谨慎考虑是否需要增加一个工厂类进行管理,增加代码的复杂度
  • 需要灵活可扩展的框架时,可以考虑采用工厂方法模式。万物皆对象,万物也皆产品类。如需要设计一个连接邮件服务器的框架,有三种网络协议可供选择:POP3,IMPA,HTTP,可以将这三种连接方法作为产品类,定义一个连接接口,使用不同的方法实现具体的产品类,再定义一个工厂方法,根据不同的条件选择不同的连接方式。若增加新的连接方式,只需要增加新的产品类即可。

3.扩展

工厂方法模式有多种扩展,而且与其它模式结合使用使用威力更大

3.1 简单工厂模式(静态工厂模式)

假如一个模块仅需要一个工厂类,没有必要把它产生出来,使用静态方法即可

去掉抽象工厂类,将工厂方法设置为静态方法

public class ProductFactory {
    // 创建一个产品对象,参数类型通常为 String, Enum, Class
    public static <T extends AbstractProduct> T createProduct(Class<T> c) {
      AbstractProduct abstractProduct = null;

      try {
          abstractProduct = (AbstractProduct) Class.forName(c.getName()).newInstance();
        } catch (Exception exception) {
          // 异常处理
        }

      return abstractProduct;
    }
}

3.2 多工厂模式

一个产品类有多个实现类,且每一个实现类的初始化还需要为对象设置一定的初始值,如果将所有的产品类放到一个工厂方法中进行初始化,必定会导致该工厂方法巨大无比,且代码结构不清晰。因此,需要为每一个产品定义一个工厂类。

多工厂模式抽象工厂类

public abstract class AbstractProductFactory {
    // 不需要为工厂方法传递参数,每一个具体的工厂方法职责明确
    public abstract AbstractProduct createProduct();
}

不同产品的工厂类,继承抽象工厂类

public class ProductOneFactory extends AbstractProductFactory {
    public AbstractProduct createProduct() {
      return new ConcreteProductOne();
    }
}

public class ProductTwoFactory extends AbstractProductFactory {
    public AbstractProduct createProduct() {
      return new ConcreteProductTwo();
    }
}

优点:创建类的职责清晰,结构简单

缺点:可扩展性及可维护性差。扩展产品类需要建立相应的工厂类,增加扩展难度及维护成本

3.3 替代单例模式

使用工厂方法模式实现单例模式

单例类

public class Singleton {
    private Singleton() {}

    public void doSomething() {
      // TODO
    }
}

负责生成单例的工厂类,使用反射方式生成单例对象

public class SingletonFactory {
    private static Singleton singleton;

    static {
      try {
          Class clazz = Class.forName(Singleton.class.getName());
          // 获取无参构造器
          Constructor constructor = clazz.getDeclaredConstructor();
          // 设置无参构造器可访问
          constructor.setAccessible(true);
          // 产生一个实例对象
          singleton = (Singleton) constructor.newInstance();
        } catch (Exception exception) {
          // 异常处理
        }
    }

    public static Singleton getSingletonInstance() {
      return singleton;
    }
}

通过获得类构造器,设置访问权限,生成一个对象,然后提供外部访问,保证内存中的对象唯一。通过工厂方法模式创建一个单例对象,该框架可以继续扩展,在一个项目中产生一个单例构造器,所有需要产生单例的类遵循一定的规则(构造器私有化),只需要输入一个类型可获得唯一的一个实例。

3.4 延迟初始化

一个对象被消费完毕后,并不立即释放,工厂类保持其初始状态。

延迟加载的工厂类

public class ProductFactory {
    private static final Map<String, AbstractProduct> prMap = new HashMap();

    public static synchronized AbstractProduct createProduct(String type) throws Exception {
      AbstractProduct product = null;

      if (prMap.containsKey(type)) {
          product = prMap.get(type);
        } else {
            if (type.equals("one")) {
              product = new ConcreteProductOne();
            } else {
              product = new ConcreteProductTwo();
            }

            prMap.put(type, product);
        }

      return product;
    }
}

通过定义一个Map容器,容纳所有产生的对象,若在Map容器中已经有的对象直接取出返回,如果没有,根据需要的类型产生一个对象,并放入到Map容器中,方便下次调用。

延迟加载框架可扩展为限制某一产品类的最大实例化数量,通过判断Map容器中已有的对象数量来实现。如JDBC连接数据库,都会要求设置一个maxConnections最大连接数量,该数量就是内存中的最大实例化数量。

(0)

相关推荐

  • 面试连环炮系列(二十二):常用的设计模式有哪些

    常用的设计模式有哪些,作用是什么 设计模式一共23种,常用的设计模式有: 工厂模式: 构建多个对象的工厂. 单例模式:单例类负责创建自己的对象,同时确保只有单个对象被创建 代理模式:代理其他类,增强原 ...

  • 创建型模式之工厂方法

    目录 定义与特点 结构与实现 模式的结构 模式的实现 应用场景 扩展:简单工厂模式 参考文章 定义与特点 工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的 ...

  • Java设计模式之003--工厂模式

    工厂模式(Factory Pattern) 是 Java 中最常用的设计模式之一. 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式. 在工厂模式中, 我们在创建对象时不会对客户端暴 ...

  • 2W 字详解设计模式

    重磅干货,第一时间送达 原文链接:javadoop.com/post/design-pattern 一直想写一篇介绍设计模式的文章,让读者可以很快看完,而且一看就懂,看懂就会用,同时不会将各个模式搞混 ...

  • 盘点c几种常见的设计模式及具体实现

    https://m.toutiao.com/is/eYr1tyt/ 1.单例模式 作用:保证一个类只有一个实例,并提供一个访问它的全局访问点,使得系统中只有唯一的一个对象实例. 应用:常用于管理资源, ...

  • 如何学习23种设计模式及其思想?

    感觉设计模式是看着简单 ,但是一用就不会,23种设计模式,学的人头大,相信大家都是这样的 设计模式在程序员的面试中会被考到,通常是介绍其原理并说出优缺点.或者对比几个比较相似的模式的异同点.在笔试中可 ...

  • 设计模式之单例模式(Singleton Pattern),太简单了

    基本定义 单例模式就是确保某一个类只有一个实例,并且提供一个全局访问点.单例模式有如下几个特点: 它只有一个实例. 它必须要自行实例化. 它必须自行向整个系统提供访问点. 代码实现 饿汉式 直接初始化 ...

  • 【7/25】使用工厂方法模式(Factory Method Pattern)创建Page页面对象

    这是<小游戏从0到1设计模式重构>系列内容第7篇,所有源码及资料在"程序员LIYI"公号回复"小游戏从0到1"获取. 看完三姐妹中的简单工厂模式,再 ...

  • PHP设计模式之工厂方法模式

    PHP设计模式之工厂方法模式 上回说到,简单工厂不属于GoF的二十三种设计模式,这回可就来真家伙了,大名顶顶的工厂方法模式前来报道! GoF类图解释 工厂方法模式对比简单工厂来说,最核心的一点,其实就 ...

  • [PHP小课堂]PHP设计模式之工厂方法模式

    [PHP小课堂]PHP设计模式之工厂方法模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式(1) 工厂方法模式

    创建型模式 简单工厂模式 工厂方法模式 IOC与工厂方法模式的结合 泛型工厂 委托工厂 创建型模式 创建型模式可以隔离客户程序对需要实例化类型的依赖关系,这类模式一般通过将实例化具体对象的职责委托给第 ...

  • 【设计模式】工厂方法模式

    定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类 优缺点 优点 针对简单工厂不容易扩展,工厂方法将实例化延迟到子类工厂,从而提供扩展 缺点 每次新增产品 ...

  • 【设计模式】工厂方法模式(Factory Method)

    工厂方法模式(Factory Method) 工厂方法模式分为三种: 1.普通工厂模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图:举例如下:(我们举一个发送邮件和短信 ...

  • 大白话工厂方法模式(Factory Method)

    目录 简单工厂模式缺陷 简单工厂模式改造 工厂方法模式定义 工厂方法模式结构 工厂方法模式分析 优点分析 缺点分析 参考文献 简单工厂模式缺陷 大白话简单工厂模式(Simple Factory Pat ...

  • 大话设计模式笔记(六)の工厂方法模式

    栗子回顾 简单工厂模式: https://www.cnblogs.com/call-me-devil/p/10926633.html 运算类使用工厂方法模式实现 UML图 代码实现 工厂接口 /** ...

  • 设计模式-工厂方法模式学习笔记

    工厂方法模式 定义 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负 ...