设计模式-工厂方法模式

120 阅读2分钟

设计模式—工厂方法模式

  • 定义

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

  • 优点:

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

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

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

      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");
          }
      }
      
    • 现在定义一个抽象的工厂类 以及一个产品的工厂类,使用泛型,包含创建产品的方法

      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;
          }
      }
      
    • 现在就可以测试工厂类去创建产品对象了

      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

      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. 多工厂模式

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

      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. 替代单例模式

      利用反射代替单例模式

      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;
          }
      }