JDK與設計模式:工廠模式

1、簡單工廠方法模式
        簡單工廠模式又稱靜態工廠方法模式。從命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用於創建對象的接口。在簡單工廠模式中,一個工廠類處於對產品類實例化調用的中心位置上,它決定那一個產品類應當被實例化。簡單工廠方法模式是一種創建型模式。
     組成:
         1) 工廠類角色:這是本模式的核心,含有一定的業務邏輯和判斷邏輯。在java中它往往由一個具體類實現。
         2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。
         3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個具體類實現。
 類圖:  
      
代碼:
   
 public  static Product createProduct(String type){
   
    if(type.equals("A")){
     return  new ConcreteProductA();
     
    }else if(type.equals("B")){
     return new ConcreteProductB();
    }else{
     return null ;
    }      
   }


2、工廠方法模式
        工廠方法模式是簡單工廠模式的進一步抽象化和推廣,工廠方法模式裏不再只由一個工廠類決定那一個產品類應當被實例化,這個決定被交給抽象工廠的子類去做。工廠方法模式是一種創建型模式。
組成:
     1) 抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。
     2) 具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。
     3) 抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在java中一般有抽象類或者接口來實現。
     4) 具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在java中由具體的類來實現。
      工廠方法模式使用繼承自抽象工廠角色的多個子類來代替簡單工廠模式中的統一工廠類。正如上面所說,這樣便分擔了對象承受的壓力;而且這樣使得結構變得靈活 起來——當有新的產品產生時,只要按照抽象產品角色、抽象工廠角色提供的合同來生成,那麼就可以被客戶使用,而不必去修改任何已有的代碼。可以看出工廠角色的結構也是符合開閉原則的!
類圖:
         

代碼:

abstract class Product{
 
 }
 
 abstract class Factory{
  public Product createProduct(){
   return null;
  }
 }
 class  ConcreteProduct extends Product{
 
 }
 
 class ConcreteFactory  extends Factory{
  public Product  createProduct(){
   return new ConcreteProduct();
  }
 }



    適用場景:客戶端不知道其所需要的對象的類。只需要知道對應的工廠,通過工廠獲取需要的產品對象。抽象工廠類通過子類來指定創建那個對象,由子類類確定具體創建那個對象,利用面向對象多態性和里氏代換原則,在運行時,子類對象覆蓋父類對象,從而使得系統更容易擴展。
   總結:在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。但是在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。

JDK中工廠方法模式應用

  
class Class<T> implements java.io.Serializable,...    {
abstract class Product{
 
 }
 
 abstract class Factory{
  public Product createProduct(){
   return null;
  }
 }
 class  ConcreteProduct extends Product{
 
 }
 
 class ConcreteFactory  extends Factory{
  public Product  createProduct(){
   return new ConcreteProduct();
  }
 }


//    通過靜態工廠方法  static Class<?> forName(String className),獲取到具體Class工廠對象。
  @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        return forName0(className, true,
                        ClassLoader.getClassLoader(Reflection.getCallerClass()));
    }
//然後通過具體Class工廠對象newInstance(),生產該工廠中的具體實例產品對象。
    @CallerSensitive
    public T newInstance()
        throws InstantiationException, IllegalAccessException
    {
        if (System.getSecurityManager() != null) {
            checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
        }

        // NOTE: the following code may not be strictly correct under
        // the current Java memory model.

        // Constructor lookup
        if (cachedConstructor == null) {
            if (this == Class.class) {
                throw new IllegalAccessException(
                    "Can not call newInstance() on the Class for java.lang.Class"
                );
            }
            try {
                Class<?>[] empty = {};
                final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
                // Disable accessibility checks on the constructor
                // since we have to do the security check here anyway
                // (the stack depth is wrong for the Constructor's
                // security check to work)
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = c;
            } catch (NoSuchMethodException e) {
                throw new InstantiationException(getName());
            }
        }
        Constructor<T> tmpConstructor = cachedConstructor;
        // Security check (same as in java.lang.reflect.Constructor)
        int modifiers = tmpConstructor.getModifiers();
        if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            if (newInstanceCallerCache != caller) {
                Reflection.ensureMemberAccess(caller, this, null, modifiers);
                newInstanceCallerCache = caller;
            }
        }
        // Run constructor
        try {
            return tmpConstructor.newInstance((Object[])null);
        } catch (InvocationTargetException e) {
            Unsafe.getUnsafe().throwException(e.getTargetException());
            // Not reached
            return null;
        }
    }




....
....

}


參考資料:《大話設計模式》、《HeadFirst設計模式》


發佈了44 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章