[创建型模式系列]Abstract factory of Design Pattern模式设计之抽象工厂模式

1 the intention of asbract factory抽象工厂模式的设计意图
        to supply interface for a series of related or depedent objects, meanwhile, you do not need to specify the concrete classes。
        提供一个创建一系列相关或者相互依赖的接口,而无需指定他们具体的类。也就是说,所创建的产品可能有很多种,在创建的时候,我们不需要指定具体的产品类型,只需要给出创建产品的工厂即可。再有相应的具体工厂来创建,而所有工厂都提供系统的接口来创建产品。
2 When to apply this pattern?
    under the  following conditions, we can apply to asbtract factory pattern
     1.one syetem needs to be independent with its production's creation, compostion and representation.
     2.one system needs  one product among many series to configue.
     3.when you supply a production class library,  at the same time  you just only wanna expose their interfaces but not implemetation.
抽象工厂模式适用情况
    在以下情况下,我们可以应用抽象工厂模式
    1.一个系统要独立于他的产品创建,组合和表示时
    2.一个系统需要多个产品系列中的一个来配置时
    3.当我们想给第三方提供一个类库,同时我们只想显示他们的接口而不是实现时。(这在软件外包和团队开发中非常有用)

3. Actor 参与者(都是抽象概念)
    AbstractFactory抽象工厂
        ---declare an interface to create abstract production.申明一个创建抽象产品对象的操作接口
    ConcreteFactory
        ---implemente  the creation about  concrete prouctions.实现创建一个具体产品的操作
    AbstractProduction
        ---declare an inferface for an abstract production   申明一类抽象产品的接口
    ConcreteProduction
        ---inplemente the concreate production object which will be created by concrete factory.
            定义一个将被相应的具体工厂创建的产品对象。
    Client
        ---just consume the interfaces that are declared as AbstractFactory and AbstractProduction.
            仅使用由AbstractFacotory和AbstractProduction类申明的接口。

4.应用举例
       在一个桌子加工厂可以生产各种类型的桌子,比如办公桌,小方桌,餐桌等等。现代的桌子生产工艺都是模块化生产。一张桌子都是由桌面和桌腿组成。我们可以生产出各种各样的桌面和桌腿,然后拼接在一起就成了我们所要得各种各样的桌子了。
    这时我们采取抽象工厂的模式来进行生产。
    首先,我们有一个工厂,叫做桌子工厂。很显然,桌子工厂是一个非常抽象的概念。
    假设我们要生产两种桌子,分别为办公桌和mini桌。因此,我们可以分为两个工厂,分别为办公桌生产工厂和mini桌生产工厂,对应模式中的具体工厂,因为我们知道,不管哪种生产工厂,其生产工艺都是一样的。因此,我们可以将其继承抽象工厂
    同时,我们知道,任何一张桌子,都是由桌腿和桌面构成的。但是,根据桌子的不同,有各种类型的桌腿,桌面。如适用于餐桌的圆形桌面,适用于办公桌的方形桌面等等。同时还有大型的适用于办公桌的大桌腿,适用于餐桌的mini腿。因此,我们可以抽象出两种产品,分别为桌面(Desktop)和桌腿(Leg)两类产品,对应于抽象工厂的AbstractProduction角色。
    然后,桌面分为方形桌面,圆形桌面等,因此,我们在创建2个桌面生产车间,分别生产圆形桌面和方形桌面。同时,我们也创建2个桌腿生产车间,分别生产大腿和mini腿。所有的桌面和桌腿用于输送到相应的工厂进行组装成桌子。
    目前,我们已经有2各工厂了,分别为办公桌生产工厂和mini桌生产工作。其中,办公桌生产工厂需要方形桌面和大腿,而mini桌生产工厂需要圆形桌面和mini腿。
    其组织结构如下图所示:

      
类图如下所示


代码如下所示:
 //桌腿的基类
    
//桌腿可以派生出各种类型的腿,比如大桌腿,小桌腿,mini桌腿等
    public abstract class  Leg
    
{
        
protected string _legName;

        
public Leg(string legName)
        
{
            _legName 
= legName;
        }


        
abstract public  string  legName();      

    }


   

    
//大号桌腿
    public class BigLeg : Leg
    
{
        
public BigLeg(string legName)
            : 
base(legName)
        
{
        
        }


        
public override string  legName()
        
{
            
return _legName;
        }

    }


    
//小号桌腿
    public class SmallLeg : Leg
    
{
        
public SmallLeg(string legName)
            : 
base(legName)
        
{

        }


        
public override string legName()
        
{
            
return _legName;
        }

    }



    
//桌面的基类
    
//桌面可以派生出各种桌面,如圆形桌面,方新桌面,椭圆形桌面等
    public abstract class Desktop
    
{
        
protected string _desktopName;
        
public Desktop(string desktopName)
        
{
            _desktopName 
= desktopName;
        }


        
abstract public string  desktopName();
    }


    
//方形桌面
    public class Rectanle_Desktop : Desktop
    
{
        
public Rectanle_Desktop(string desktopName)
            : 
base(desktopName)
        
{

        }

        
public override string  desktopName()
        
{
            
return _desktopName;
        }

    }


    
//圆形桌面
    public class Circle_Desktop : Desktop
    
{
        
public Circle_Desktop(string desktopName)
            : 
base(desktopName)
        
{

        }


        
public override string  desktopName()
        
{
            
return _desktopName;
        }

    }


    
//工厂抽象类
    public abstract class Factory
    
{
        
protected Leg leg;
        
protected Desktop desktop;
        
public abstract Leg CreateLeg();
        
public abstract Desktop CreateDesktop();
        
public void Composite()
        
{
            Console.WriteLine(
"Desktop Name:{0} +Leg Name:{1}", desktop.desktopName(),leg.legName());
        }

    }


    
public class MiniTableFactory : Factory
    
{
        
public override Leg CreateLeg()
        
{
            leg
=new SmallLeg("Disney");
            
return leg;
        }


        
public override Desktop CreateDesktop()
        
{           
             desktop
=new Circle_Desktop("Disney");
             
return desktop;
        }

    }


    
public class BigTableFactory : Factory
    
{
        
public override Leg CreateLeg()
        
{
            leg
=new  BigLeg("BigLeg");
            
return leg;
         
        }


        
public override Desktop CreateDesktop()
        
{
           desktop
=new Rectanle_Desktop("Rectangle Desktop");
           
return desktop;
        }

    }



public class program
{
    Factory factory 
= new MiniTableFactory();
            factory.CreateDesktop();
            factory.CreateLeg();
            factory.Composite();

            Console.WriteLine(
"-----------------------------------------");
            Factory factoryBig 
= new BigTableFactory();
            factoryBig.CreateDesktop();
            factoryBig.CreateLeg();
            factoryBig.Composite();}

运行结果:
Desktop Name :Disney +Leg Name:Disney  //mini桌
--------------------------
Desktop Name:Rectangle Desktop +Leg Name:BigLeg //    办公桌


5.关于系统的扩展(开放-封闭性)
1,可扩展性。 
        假设工厂需要生产餐桌。此时,我们只需要增加一个具体工厂以及其具体产品即可。其他地方无需修改
2.合作性
        假设我们需要让第三方去生产产品。这是我们需要将我们的代码交付给第三方。但是处于版权的考虑,我们只需要将抽象工厂类和抽象产品类交付即可。工厂的加工和产品的生产细节无需让他们知道。因为不管是什么产品,我们都是提供的统一接口。例如,我们不管生产什么类型的桌子,都是factory.CreateDesktop()-->factory->CreateLeg()-->factory->Composite()。 只是,给定什么样的工厂,其就生产相应类型的桌子。
【推广】 免费学中医,健康全家人
原文地址:https://www.cnblogs.com/Winston/p/1194995.html