设计模式-工厂模式

来源:互联网 发布:算法设计与分析(第2版) 编辑:程序博客网 时间:2024/06/04 18:50

简单工厂模式

1.为什么要使用工厂模式

直接目的:避免在代码中出现大量的new关键字

根本目的:将对象的创建统一起来便于维护和整体把控

这一点可以理解,加入你在项目中new了某个对象100次,一年后由于业务逻辑变更,构造方法多了一个参数,你会怎么办?你应该会这么做:找到这100个对象new的地方,用新的构造方法来创建对象,你重复劳动了100次,假如采用工厂模式,你只用改一次:把创建工厂给改一下就好了。这就是工厂模式最简单最直接的好处。

2.工厂模式的示例

下面是最常见的一个示范,其实它的原理就是面向对象中的多态+接口编程,虽然返回的都是Car类型,但是drive的时候会调用真正的实例中的对应方法。按照抽象类和接口的意义归属,Car应该被定义成抽象类,因为Benz、Bmw和Car的关系是继承关系,而接口表示的一组行为。但是,为什么这里还要定义成接口,是因为Java和.NET不支持多继承,如果继承了Car,就无法继承其他类,有时候业务需要必须继承其他类,这个时候代码就不能用了。当然,C++中支持多继承,因此可以在C++中使用抽象类,另外C++没接口的概念,但你可以模拟接口。这里只介绍简单工厂模式,至于剩下两种工厂模式,我觉得更没有使用价值。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. interface Car {  
  2.     void drive();  
  3. }  
  4.   
  5. class Benz implements Car {  
  6.   
  7.     @Override  
  8.     public void drive() {  
  9.         System.out.println("drive Benz");  
  10.     }  
  11.   
  12. }  
  13.   
  14. class Bmw implements Car {  
  15.   
  16.     @Override  
  17.     public void drive() {  
  18.         System.out.println("drive Bmw");  
  19.     }  
  20.   
  21. }  
  22.   
  23. class CarFactory {  
  24.     public static Car creator(String carType) {  
  25.         if (carType.equals("Benz")) {  
  26.             return new Benz();  
  27.         } else if (carType.equals("Bmw")) {  
  28.             return new Bmw();  
  29.         } else {  
  30.             throw new UnsupportedOperationException("car with type" + carType  
  31.                     + " is not supported.");  
  32.         }  
  33.     }  
  34. }  
  35.   
  36. public class A {  
  37.     public static void main(String args[]) {  
  38.         Car benz = CarFactory.creator("Benz");  
  39.         benz.drive();  
  40.         Car bmw = CarFactory.creator("Bmw");  
  41.         bmw.drive();  
  42.     }  
  43. }  

上述代码是没啥用的,看一个实际使用的例子。下面这个工厂模式的意义在于能够统一管理所有的业务管理器,仅此而已。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 管理器的工程,初始化所有业务的管理器 
  3.  */  
  4. public class ManagerFactory {  
  5.     // 缓存管理器实例的集合  
  6.     private transient Map<Byte, IManager> mManagerMap = null;  
  7.   
  8.     private static ManagerFactory sIntance = new ManagerFactory();  
  9.   
  10.     private ManagerFactory() {  
  11.         mManagerMap = new HashMap<Byte, IManager>();  
  12.     }  
  13.   
  14.     public ManagerFactory getInstance() {  
  15.         return sInstance;  
  16.     }  
  17.   
  18.     /** 
  19.      * 获取管理器实例 
  20.      *  
  21.      * @param context  上下文 
  22.      * @param id  管理器ID 
  23.      * @return  管理器实例 
  24.      */  
  25.     protected IManager getManager(final Context context, final byte id) {  
  26.         IManager manager = mManagerMap.get(mId);  
  27.   
  28.         if (manager == null) {  
  29.             switch (id) {  
  30.             case DB_ID:  
  31.                 manager = new DBManager(context);  
  32.                 break;  
  33.             case DOWNLOAD_ID:  
  34.                 manager = new DownloadManager(context);  
  35.                 break;  
  36.             case NETWORK_ID:  
  37.                 manager = new NetworkManager();  
  38.                 break;  
  39.             case IMAGE_ID:  
  40.                 manager = new ImageManager();  
  41.                 break;  
  42.             default:  
  43.                 break;  
  44.             }  
  45.             mManagerMap.put(id, manager);  
  46.         }  
  47.   
  48.         return manager;  
  49.     }  
  50. }  

工厂模式为什么没有太大价值

1.有利有弊

优点:将对象的创建统一起来便于维护和整体把控,对扩展开放,对修改封闭

缺点:耦合性提高,由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中,这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。

2.使用有限制

从工厂模式的示例可以看出:工厂模式需要类实现它的接口并且在业务内部存在明显的继承关系,比如汽车和奔驰宝马的关系。而继承关系往往存在于模型之间,业务之间很难存在继承关系,因此如果业务内部或者业务之间没有这种显式的继承关系该咋办?就算业务内部有继承关系,各个业务交给你统一管理,这样就会提高代码的耦合性,当创建逻辑复杂的时候,工厂方法就很复杂,容易产生干扰。

3.其开闭性优点很容易被替代

可以通过高度层次化和模块化来提高系统的开闭性,而不必生硬地去套用工厂模式。

0 0
原创粉丝点击