抽象工厂模式

抽象工厂模式,这里借鉴了 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文件(相应的产品类别[产品接口] 和 产品具体类)。
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章