设计模式—工厂方法模式

  • 定义

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

  • 优点:

    • 良好的封装性,代码结构清晰
    • 良好的扩展性
    • 典型的解耦架构
  • 代码

    • 首先定义一个产品的接口

      1
      2
      3
      public interface Product {
      void say();
      }
    • 然后定义产品A,产品B 实现产品接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      public class ProductA implements Product {

      @Override
      public void say() {
      System.out.println("this is product A");
      }
      }

      public class ProductB implements Product {

      @Override
      public void say() {
      System.out.println("this is product B");
      }
      }
    • 现在定义一个抽象的工厂类 以及一个产品的工厂类,使用泛型,包含创建产品的方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      public abstract class AbstractProductFactory {
      public abstract <T extends Product> T createProduct(Class<T> cls);
      }


      public class ProductFactory extends AbstractProductFactory {

      @Override
      public <T extends Product> T createProduct(Class<T> cls) {
      Product product = null;
      try {
      product = (Product) Class.forName(cls.getName()).newInstance();
      // product = cls.newInstance();
      } catch (Exception e) {
      e.printStackTrace();
      }
      return (T) product;
      }
      }
    • 现在就可以测试工厂类去创建产品对象了

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      public class ProductFactoryTest {

      @Test
      public void testFactory(){
      AbstractProductFactory factory = new ProductFactory();
      Product a = factory.createProduct(ProductA.class);
      a.say();
      ProductB b = factory.createProduct(ProductB.class);
      b.say();

      }

      }

      从上面创建对象的方式可以看出没有使用new 关键字,也就实现了解耦

    扩展

    1. 简单工厂模式

      ​ 当一些模块只需要一个工厂类的时候,没有必要将工厂类实例化出来,这是就可以使用简单工厂模式来实现,去掉抽象工厂类并将工厂类的方法设为static

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public class SimpleProductFactory {

      public static <T extends Product> T createProduct(Class<T> cls){
      Product product = null;
      try {
      product = (Product) Class.forName(cls.getName()).newInstance();
      } catch (Exception e) {
      e.printStackTrace();
      }
      return (T) product;
      }
      }
    2. 多工厂模式

      ​ 当项目比较复杂且产品的实现类比较多时,可以考虑为每个产品创建一个工厂类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      public  abstract class MultiAbstractFactory {

      public abstract Product createProduct();

      }

      public class ProductAFactory extends MultiAbstractFactory {
      @Override
      public Product createProduct() {
      return new ProductA();
      }
      }

      public class ProductBFactory extends MultiAbstractFactory {
      @Override
      public Product createProduct() {
      return new ProductB();
      }
      }
    3. 替代单例模式

      利用反射代替单例模式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      public class Singleton {
      //私有构造
      private Singleton(){}
      }

      public class SingletonFactory {
      private static Singleton singleton;

      static {
      try {
      Class cls = Class.forName(Singleton.class.getName());
      Constructor constructor = cls.getDeclaredConstructor();
      constructor.setAccessible(true);
      singleton = (Singleton) constructor.newInstance();
      } catch (Exception e) {
      e.printStackTrace();
      }
      }

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