zoukankan      html  css  js  c++  java
  • Abstract Factory (抽象工厂) — 【面向对象设计模式学习】

    Abstract Factory (抽象工厂) — 【面向对象设计模式学习】

    By CityWalker 2010年3月17日

    Intent

    Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

    Applicability

    a)         A system should be independent of how its products are created, composed, represented.

    b)         A class can’t anticipate the class of objects it must create.

    c)         A system must use just one of a set of families of products but has more.

    d)         A family of related product object is designed to be used together, and you need to enforce this constraint.

    Structure

     

    Example

    就以网上比较经典的Real-World例子来说吧

    ClassDiagram:

    抽象工厂模式中与本例中的各个对象的对应关系说明:

    Abstract Factory:  ContinentFactory                     

    Concrete Factory1:  AfricaFactory

    Concrete Factory2:  AmericaFactory

    Abstract ProductA:  Herbivore

    Abstract ProductB:  Carnivore

    Concrete ProductA1: Wildebeest

    Concrete ProductB1: Lion

    Concrete ProductA2: Bison

    Concrete ProductB2: Wolf

    抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。

    具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。

    抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

    具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

    —— 摘自 吕震宇“C#设计模式(6)-Abstract Factory Pattern

    主要代码:

    public abstract class ContinentFactory
        {
            public abstract Herbivore CreateHerbivore();
    
            public abstract Carnivore CreateCarnivore();
        }
    public sealed class AfricaFactory : ContinentFactory
        {
            private static readonly AfricaFactory instance = new AfricaFactory();
    
            AfricaFactory()
            {
                
            }
    
            static AfricaFactory()
            {
                
            }
    
            public static AfricaFactory Instance
            {
                get
                {
                    return instance;
                }            
            }       
    
    
            public override Herbivore CreateHerbivore()
            {
                return new Wildebeest();
            }
    
            public override Carnivore CreateCarnivore()
            {
                return new Lion();
            }
        }
    
    public abstract class Herbivore
        {
        }
    public abstract class Carnivore
        {
            public abstract void Eat(Herbivore herbivore);
        }
    public class Wildebeest : Herbivore
        {
        }
    public class Lion : Carnivore
        {
            public override void Eat(Herbivore herbivore)
            {
                Console.WriteLine(this + " eats " + herbivore + "\n");
            }
        }
    
    public class AnimalWorld
        {
            private Herbivore herbivore;
            private Carnivore carnivore;
    
            public AnimalWorld(ContinentFactory cf)
            {
                herbivore = cf.CreateHerbivore();
                carnivore = cf.CreateCarnivore();
            }
    
            public void RunFoodChain()
            {
                carnivore.Eat(herbivore);
            }
        }
    

    Client:

    ContinentFactory cf = AfricaFactory.Instance;
    
                AnimalWorld world = new AnimalWorld(cf);
                world.RunFoodChain();
    
                Console.ReadKey();
    

    一个应用中一般每个产品系列只需一个具体工厂的实例,因此,具体工厂采用Singleton模式实现。可以看出客户端并不依赖于多个产品对象的创建、组合和表达的细节,所有产品均以同样的接口出现,很好地应对了“多系列对象创建”的需求变化。

        此外,Abstract Factory在增加“产品族”需求变化方面也很好地体现了“开放-封闭”原则。假如现在我要增加一个“地域族”—Asia,则只需做如下事情:

    1.  增加 AsiaFactory

    public sealed class AsiaFactory : ContinentFactory
        {
            private static readonly AsiaFactory instance = new AsiaFactory();
    
            AsiaFactory()
            { }
    
            static AsiaFactory()
            { }
    
            public static AsiaFactory Instance
            {
                get
                {
                    return instance;
                }
            }
    
            public override Herbivore CreateHerbivore()
            {
                return new Sheep();
            }
    
            public override Carnivore CreateCarnivore()
            {
                return new Tiger();
            }
        }
    

    2.  增加 亚洲地区的 草食动物和肉食动物类

    public class Sheep : Herbivore
        {
    
        }
    public class Tiger : Carnivore
        {
            public override void Eat(Herbivore herbivore)
            {
                Console.WriteLine("[Asia Version] —— " + this + " eats " + herbivore);
            }
        }
    

    3.  修改客户端调用

    ContinentFactory cf = AsiaFactory.Instance;

    其他地方均不需要修改,此所谓“对扩展开放”。但是如果要增加新的产品,比如增加一种食肉动物或者草食动物,则需要修改所有的工厂角色,没有支持上述原则,不过正所谓“尺有所短寸有所长”每种模式其实都有它适用的情况,我们只有把握住这一点,灵活应用才是学习设计模式的最终目的。另外,对于修改客户端方面,还可以利用反射和配置文件来提高部署的灵活性,比较简单就不赘述了。

    Conclusion

    Benefits

    a)         Isolates client from concrete implementation classes. The “factory” object has the responsibility for providing creation services for entire platform family. Client never create platform object directly, they ask factory to do that for them.

    b)         Makes exchanging product family easy, since a concrete factory can support a complete        family of products.

    c)         Enforces the use of products only from one family.

    Liabilities

             Supporting new kinds of product requires changing the AbstractFactory interface.

  • 相关阅读:
    hrbust 1558 小背包(简单01背包)水坑
    hrbust 1174泉水(DFS深度优先搜索)
    HDU 1115
    HDU 4273
    HDU 2912
    POJ 3528
    HDU 1912
    HDU 4741
    HDU 4617
    POJ 1755
  • 原文地址:https://www.cnblogs.com/Reborn/p/1688192.html
Copyright © 2011-2022 走看看