场景 
new 对象的替代方案 
需要灵活、可扩展的框架时 
在异构项目中,从外部产生的对象 
测试驱动开发框架下使用。测试驱动开发 -TDD
  
 
工厂方法模式 定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;
优点 
良好的封装,代码结构清晰,降低模块间的耦合; 
良好的扩展性; 
屏蔽具体的产品类,只要接口不变,系统中上层模块就不需要发生变化。 
 
高层模块只需要知道产品的抽象类,不关心实现类,符合迪米特法则;
缺点 对于不同类型的产品都要增加不同类型的工厂来管理,增加代码的复杂性
实现 通用实现 产品类:
1 2 3 4 5 6 7 8 9 10 11 12 public  abstract  class  Product     public  abstract  void  method1 ()      public  void  method2 ()  } public  class  Product1  extends  Product     public  void  method1 ()  } public  class  Product2  extends  Product     public  void  method1 ()  } 
工厂类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  abstract  class  Factory     public  abstract  <T extends Product> T create (Class<T> c)  ; } public  class  ConcreteFactory  extends  Factory     public  <T extends Product> T create (Class<T> c)  {         Product p = null ;         try {             p = (Product)Class.forName(c.getName()).newInstance();         }catch (Exception e){         }         return  (T)p;     } } 
使用:
1 2 Factory factory = new ConcreteFactory(); Product p = factory.createt(Product1.class); 
缩小为简单工厂 去掉抽象的Factory类,create()方法变为静态方法即可。
1 2 3 4 5 6 7 8 9 10 11 12 public  void  Factory{    public  static  <T extends Product> T create (Class<T> c)  {         Product p = null ;         try {             p = (Product)Class.forName(c.getName()).newInstance();         }catch (Exception e){         }         return  (T)p;     } } 
调用代码:
1 Product p = Factory.create(Product1.class ) ; 
升级为多个工厂类 遇到复杂情况下,一个工厂类初始化需要耗费很多资源,这样可以将工厂类细化拆分。
1 2 3 4 5 6 7 8 9 10 11 12 public  class  Factory1  extends  Factory   public  static  Product create ()      return  new  Product1();   } } public  class  Factory2  extends  Factory   public  static  Product create ()      return  new  Product2();   } } 
这样的好处是职责清晰,结构简单,但是可扩展性和可维护性差了些。
替代单例模式 通过反射的方式来创建唯一一个实例
延迟初始化 一个对象被使用完毕后,并不立即释放,工厂类保持其初始状态,等待再次被使用。
延迟加载框架可以被扩展为,限制某个产品类的最大实例化数量(如链接池的最大链接数量)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public  class  ProductFactory     private  static  final  Map<String,Product> pMap = new  HashMap();     public  static  synchronized  Product createProduct (String type)  throws  Exception         Product p = null ;         if (pMap.containsKey(type)){             p = pMap.get(type);         }else {             if (type.equals("Product1" )){                 p = new  Product1();             }else {                 p = new  Product2();             }         }         return  product;     } } 
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
 
https://www.zhihu.com/question/24843188 
https://www.jianshu.com/p/83ef48ce635b 
https://blog.csdn.net/buyulian/article/details/79203880 
https://blog.csdn.net/qianhaifeng2012/article/details/52014773 
https://www.cnblogs.com/aspirant/p/8980573.html 
http://www.akathink.com/2016/08/01/%E5%BD%BB%E5%BA%95%E6%90%9E%E6%87%82%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/