抽象工廠模式

抽象工廠模式,這裏借鑑了 2  篇文章。

文章一:java版本的例子:
抽象工廠模式是對象的創建模式,它是工廠方法模式的進一步推廣。
 
抽象工廠模式可以向客戶端提供一個接口,使得客戶端在不必指定具體產品類型的情況下,創建多個產品族中的產品,這就是抽象工廠模式的用意。
 
每個模式都是針對一定問題的解決方案,抽象工廠模式面對的問題是多個產品等級結構的系統設計。
 
抽象工廠模式中涉及到兩個概念:產品族和產品等級結構
產品族:是指位於不同產品等級結構中,功能相關聯的產品組成的家族,比如:麥當勞和肯德基,這兩個產品有不同的分店,北京有家麥當勞和肯德基店,上海也有家,北京的麥當勞和北京的肯德基組成一個產品族。
產品等級結構:北京的麥當勞和上海的麥當勞組成了一個產品等級結構。
示意圖如下:
chanpingdengji
 
 
 
 
 
UML
 
 
抽象工廠模式的結構
涉及到四個角色
1)抽象工廠角色:是抽象工廠方法模式的核心,與應用系統的商業邏輯無關。通過使用java接口或抽象類實現,而 所有的具體工廠類必須實現這個角色。
2)具體工廠角色:這個角色直接在客戶端的調用下創建產品的實例,這個角色含有選擇合適的產品對象的邏輯,通常使用
java類實現這個角色。
3)抽象產品角色:所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口,通常由java接口或抽象
類實現。
4)具體產品角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例,這是客戶端最終需要的,通常由 java類實現.
 
/**    
* 抽象產品角色    
* @author Administrator    
*    
*/
    
public interface KfcBread        
{        
}    


/**    
* 具體產品角色    
* @author Administrator    
*    
*/
    
public class ShangHaiKfc implements KfcBread        
{        
        public ShangHaiKfc()        
        {        
                System.out.println("肯德基出生地:上海");        
        }        
}    

/**    
* 具體產品角色    
* @author Administrator    
*    
*/
    
public class BeiJingKfc implements KfcBread        
{        
        public BeiJingKfc()        
        {        
                System.out.println("肯德基出生地:北京");        
        }        
}    


/**    
* 抽象產品角色    
* @author Administrator    
*    
*/
    
public interface McdBread        
{        
}    


/**    
* 具體產品角色    
* @author Administrator    
*    
*/
    
public class ShangHaiMcd implements McdBread        
{        
        public ShangHaiMcd()        
        {        
                System.out.println("麥當勞出生地:上海");        
        }        
}    


/**    
* 具體產品角色    
* @author Administrator    
*    
*/
    
public class BeiJingMcd implements McdBread        
{        
        public BeiJingMcd()        
        {        
                System.out.println("麥當勞出生地:北京");        
        }        
}    


/**    
* 抽象工廠角色    
* @author Administrator    
*    
*/
    
public interface Toaster        
{        
        KfcBread toastKFC();        
                
        McdBread toastMCD();        
}    

/**    
* 具體工廠角色    
* @author Administrator    
*    
*/
    
public class ShangHaiToaster implements Toaster        
{        
        public KfcBread toastKFC()        
        {        
                return new ShangHaiKfc();        
        }        
    
        public McdBread toastMCD()        
        {        
                return new ShangHaiMcd();        
        }        
}    


/**    
* 具體工廠角色    
* @author Administrator    
*    
*/
    
public class BeiJingToaster implements Toaster        
{        
        public KfcBread toastKFC()        
        {        
                return new BeiJingKfc();        
        }        
    
        public McdBread toastMCD()        
        {        
                return new BeiJingMcd();        
        }        
}    



/**    
* 測試類    
* @author Administrator    
*    
*/
    
public class client        
{        
        public static void main(String[] args)        
        {        
                Toaster t1 = new BeiJingToaster();        
                Toaster t2 = new ShangHaiToaster();        
                        
                McdBread mcd1 = t1.toastMCD();        
                McdBread mcd2 = t2.toastMCD();        
                        
                KfcBread kfc1 = t1.toastKFC();        
                KfcBread kfc2 = t2.toastKFC();        
        }        
}    
 
 
這段代碼中有個問題:就是在具體的工廠中增加相應的具體產品的話,要去修改具體工廠中的代碼,這和軟件開發的“接納增加,避免修改”是相矛盾的。
 
 
文章二:.Net版本。
 
現在有這樣一個需求:
老闆:我要做一種產品。
程序員:我們沒有考慮,直接做了一個產品類(ProductA1)和 產品線ProductFactory1。
老闆:我還要再做另一種產品。
程序員:我們沒有考慮,又做了一個產品類(ProductA2)。
老闆:我還要再做另一種產品。
程序員:我們沒有考慮,又做了一個產品類(ProductB1)。
老闆:我還要再做另一種產品。
程序員:憤怒,又做了一個產品類(ProductB2)。
老闆:使用中。。。
程序員:怕了他了,所以做了一個擴展, 抽象出來 AbstractProductA AbstractProductB。
老闆:經過使用我們發現要新增我們的產品線來提高效率
程序員:沒考慮,怎加了產品線ProductFactory2。
老闆:經過我們的考慮兩條產品線還是不能滿足要求。
程序員:怕了他了,所以做了一個擴展 抽象出來AbstractFactory。

到現在我們看似完成了,其實是一團糟,讓我們看看都做了什麼,當我們產品類需要增加一個方法時,需要改寫產品類的同時
要怎加產品線方法和產品線接口,更遭的是要增加產品線。依賴關係依然沒有太大改善。

現在我們解決它:

 
 
實現:下面是一個接口的例子(我懶得改成抽象類,道理是一樣的)。
interface IFactory
        {
                object CreateProduct(string className);
        }

class ProductFactory:IFactory
        {
                object CreateProduct(string className)
                {
                        string path = "*.dll";
                        return Assembly.Load(path).CreateInstance(path + className);
                }
        }


dll內容:
        public interface IProductA { }
        public class ProductA1 : IProductA { }
        public class ProductA2 : IProductA { }

        public interface IProductB { }
        public class ProductB1 : IProductB { }
        public class ProductB2 : IProductB { }


static void Main(string[] args)
{
  IFactory factory = new ProductFactory();
                IProductA productA = (IProductA)factory.CreateProduct("ClassName");
}
 
 
這裏也有個地方需要補充下:
當有多個產品工廠的時候,只需要增加相應的工廠類,同事增加相應的dll文件(相應的產品類別[產品接口] 和 產品具體類)。
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章