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

来源:互联网 发布:广州linux运维培训 编辑:程序博客网 时间:2024/05/21 01:47

原文:http://blog.csdn.net/hackerain/article/details/7531049

定义:

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

通用类图:


代码如下:

[java] view plaincopy
  1. public abstract class Product {  
  2.     public void method1(){  
  3.         System.out.println("method1 invoked");  
  4.     }  
  5.       
  6.     public abstract void method2();  
  7. }  
[java] view plaincopy
  1. public class ConcreteProduct1 extends Product {  
  2.   
  3.     @Override  
  4.     public void method2() {  
  5.         System.out.println("product1 method2 invoked");  
  6.     }  
  7.   
  8. }  
[java] view plaincopy
  1. public abstract class Creator {  
  2.     /** 
  3.      * 创建一个产品对象,其输入参数类型可以自行设置 
  4.      * 通常为String、Enum、Class等,当然也可以为空 
  5.      * @param c 
  6.      * @return 
  7.      */  
  8.     public abstract <T extends Product> T createProduct(Class<T> c);  
  9. }  
[java] view plaincopy
  1. public class ConcreteCreator extends Creator {  
  2.   
  3.     @Override  
  4.     public <T extends Product> T createProduct(Class<T> c) {  
  5.         Product product=null;  
  6.         try {  
  7.             product=(Product)Class.forName(c.getName()).newInstance();  
  8.         } catch (Exception e) {  
  9.             e.printStackTrace();  
  10.         }  
  11.         return (T)product;  
  12.     }  
  13.   
  14. }  

工厂方法模式的优点:

1、良好的封装性,代码结构清晰

2、扩展性很好

3、屏蔽产品类


工厂模式的扩展:

1、缩小为简单工厂模式

即一个模块仅需要一个工厂类,没有必要使用抽象类,使用静态的方法就可以了。代码如下:

[java] view plaincopy
  1. public class SimpleCreator {  
  2.       
  3.     public static <T extends Product> T createProduct(Class<T> c){  
  4.         Product product=null;  
  5.         try {  
  6.             product=(Product)Class.forName(c.getName()).newInstance();  
  7.         } catch (Exception e) {  
  8.             e.printStackTrace();  
  9.         }  
  10.         return (T)product;  
  11.     }  
  12.       
  13. }  

简单工厂模式的缺点是工厂类的扩展比较困难,不符合开闭原则,但是非常实用。


2、升级为多个工厂类

即针对每一种产品,单独创建一个工厂类,而不是混合在一起,根据传入参数的类型判断要产生哪种产品,这样的方法更符合单一职责原则,类图如下:

源代码如下:

[java] view plaincopy
  1. public abstract class Creator {  
  2.     public abstract Product createProduct();  
  3. }  
[java] view plaincopy
  1. public class Product1Creator extends Creator {  
  2.   
  3.     @Override  
  4.     public Product createProduct() {  
  5.         return new ConcreteProduct1();  
  6.     }  
  7.   
  8. }  
[java] view plaincopy
  1. public class Product2Creator extends Creator {  
  2.   
  3.     @Override  
  4.     public Product createProduct() {  
  5.         return new ConcreteProduct2();  
  6.     }  
  7.   
  8. }  
多工厂类应用在每个实现类的初始化都不一样的情况下,而这种情况更为普遍,但是这样就增加了维护的难度,一种产品就有一个对应的工厂类。当然,也可以将各个子工厂类进行封装,向外提供统一的接口,这样就避免了代码混乱。


3、替代单例模式

前面所说的单例模式有一定的缺点,比如说对测试不利,因为它没有接口,不能用来mock的方法虚拟一个对象。我们可以用工厂方法模式的方法,来写一个单例模式的例子,抓住主要矛盾:单例模式要求在内存中,只存在一个实例。其类图如下:


代码如下:

[java] view plaincopy
  1. public class Singleton {  
  2.       
  3.     //定义成私有的构造函数,防止被外部实例化  
  4.     private Singleton(){  
  5.         System.out.println("Singleton is created");  
  6.     }  
  7.       
  8.     public void doSomething(){  
  9.         System.out.println("do something...");  
  10.     }  
  11. }  
[java] view plaincopy
  1. public class SingletonFactory {  
  2.     private static Singleton singleton;  
  3.       
  4.     static{  
  5.         try{  
  6.             Class clss=Class.forName(Singleton.class.getName());  
  7.               
  8.             //获得无参构造函数  
  9.             Constructor constructor=clss.getDeclaredConstructor();  
  10.               
  11.             //设置无参构造函数是可访问的  
  12.             constructor.setAccessible(true);  
  13.               
  14.             //产生一个实例  
  15.             singleton=(Singleton)constructor.newInstance();  
  16.         }catch(Exception e){  
  17.             e.printStackTrace();  
  18.         }  
  19.     }  
  20.       
  21.     public static Singleton getSingleton(){  
  22.         return singleton;  
  23.     }  
  24. }  


4、延迟初始化

延迟初始化,即一个对象被消费完后,并不立即释放,工厂类保存其初始状态,等待再次被使用,通用类图如下:

延迟工厂类代码如下:

[java] view plaincopy
  1. public class LazyCreator {  
  2.     private static final Map<String,Product> map=new HashMap<String,Product>();  
  3.       
  4.     public static synchronized Product createProduct(String key){  
  5.         Product product=null;  
  6.         if(map.containsKey(key)){  
  7.             return map.get(key);  
  8.         }  
  9.         else{  
  10.             if(key.equals("Product1")){  
  11.                 product=new ConcreteProduct1();  
  12.             }  
  13.             else if(key.equals("Product2")){  
  14.                 product=new ConcreteProduct2();  
  15.             }  
  16.             map.put(key, product);  
  17.         }  
  18.         return product;  
  19.     }  
  20. }  

0 0
原创粉丝点击