zoukankan      html  css  js  c++  java
  • AbstractFactory抽象工厂模式(创建型模式)

    1、new 的问题

    常见的对象创建方法:

    //创建一个Road对象
    Road road=new Road();

    new的问题:实现依赖,不能应对具体实例的变化

    怎么理解上面这句话呢?

    可以这样理解:我们创建的对象实例依赖于Road对象的内部实现,如果Road对象不会发生变化(或者发生变化的频率很小),那么单纯的用new是可以的,但是上面的Road我们单纯籽籽棉意思上理解,路肯定是变化很大的,路有水泥路,马路,公路等等,所以每当我们的Road发生变化,单纯用new的方式,我们就必须修改所有使用过Road的地方。

    总结:所以可以得出一个结论,当我们new的业务对象变化比较频繁的时候,就不能使用new来创建对象;如果要创建的业务对象很稳定,不会发生平凡的变化,那么可以使用new. 

    2、如何解决new的问题呢?

    解决new的问题,最好的方法就是封装变化点,哪里经常变化,就把那里封装起来

    3、工厂模式源起

    (1)、2中说了,要解决new的问题,就是封装变化点,而new的问题就是"对象创建的不定性",对象的频繁变化,所以我们就封装"对象的创建"。

    (2)、这也引申出了另一个编程思想:面向接口编程---依赖接口,而非依赖实现

    (3)、抽象工厂的简易版:

    using System;
    namespace AF
    {
        class AbstractFactorySimple
        {
            static void Main(string[] args)
            {
                //创建一个Road对象
                Road road = AbstractFactory.CreateRoad();
            }
        }
        public class AbstractFactory
        {
            public static Road CreateRoad()
            {
                return new Road();
            }
        }
        class Road
        {
    
        }
    }

    4、假设有一个游戏开发场景:我们需要构造"道路"、"房屋"、"地道"、"丛林"等等对象,可以用下面的最浅层的工厂模式来封装

    using System;
    namespace AF
    {
        class AbstractFactoryShallow
        {
    
        }
        public class AbstractFactory
        {
            public static Road CreateRoad() { return new Road(); }
            public static Jungle CreateJungle() { return new Jungle(); }
            public static Buliding CreateBuliding() { return new Buliding(); }
            public static Postern CreatePostern() { return new Postern(); }
        }
        class Road { }
        class Jungle { }
        class Buliding { }
        class Postern { }
    }

    上面的代码是最浅层的封装,也就是简单的工厂,也称之为"静态工厂";解决了对象创建的不确定性;

    5、这个时候需求又变了,接着第四个问题,一般游戏都会有不同的风格,所以"道路","暗道","丛林","房屋"也会有不同的风格,这个时候在解决对象创建的不确定之后,产生了对象的不决定性,也就是道路对象可能会有很多种,丛林也可能会有很多种,等等的问题,那么显然上面的简单工厂(静态工厂)并不能解决我们的问题;

    在提出上面问题的解决方案之前,先说下动机:

    在软件系统中,经常面临着"一系列相互依赖的对象创建",而随着业务需求的改变,往往存在更多系列对象的创建

    解决方法:绕过常规的对象创建方法,提供一种"封装机制",来避免客户程序和多系列对象创建的紧耦合。

    ,如果不理解前面的概念,可以4中的分析;

    6、抽象工厂的意图

    提供一个接口,让接口负责创建一系列"相关或者相互依赖"的对象,无须指定具体的类。

                                                                                   

     7、结构图

    8、完整工厂代码

    using System;
    
    namespace AF
    {
        //抽象工厂层
        public abstract class Road 
        {
            public abstract void AAA(Jungle jungle);
        }
        public abstract class Jungle 
        {
            public abstract void BBB();
        }
        public abstract class Building 
        {
            public abstract void CCC();
        }
        public abstract class Tunnel 
        {
            public abstract void DDD();
        }
        public abstract class AbstractFactory
        {
            public abstract Road CreateRoad();
            public abstract Jungle CreateJungle();
            public abstract Building CreateBuilding();
            public abstract Tunnel CreateTunnel();
        }
        //抽象工厂层
    
        //现代工厂层
        public class ModernRoad :Road
        {
            public override void AAA(Jungle jungle) { }
        }
        public class ModernJungle : Jungle
        {
            public override void BBB() { }
        }
        public class ModernBuilding : Building
        {
            public override void CCC()
            {
                throw new NotImplementedException();
            }
        }
        public class ModernTunnel : Tunnel
        {
            public override void DDD()
            {
                throw new NotImplementedException();
            }
        }
        public class ModernFactory : AbstractFactory
        {
            public override Road CreateRoad()
            {
                return new ModernRoad();
            }
            public override Jungle CreateJungle()
            {
                return new ModernJungle();
            }
            public override Building CreateBuilding()
            {
                return new ModernBuilding();
            }
            public override  Tunnel CreateTunnel()
            {
                return new ModernTunnel();
            }
        }
        //现代工厂层结束
    
        //古典工厂层
        public class ClassicalRoad : Road
        {
            public override void AAA(Jungle jungle)
            {
            }
        }
        public class ClassicalJungle : Jungle
        {
            public override void BBB()
            {
            }
        }
        public class ClassicalBuiliding : Building
        {
            public override void CCC()
            {
    
            }
        }
        public class ClassicalTunnel : Tunnel
        {
            public override void DDD()
            {
            }
        }
        public class ClassicalFactory : AbstractFactory
        {
            public override Road CreateRoad()
            {
                return new ClassicalRoad();
            }
    
            public override Jungle CreateJungle()
            {
                return new ClassicalJungle();
            }
    
            public override Building CreateBuilding()
            {
                return new ClassicalBuiliding();
            }
    
            public override Tunnel CreateTunnel()
            {
                return new ClassicalTunnel();
            }
        }
        //古典工厂层结束
    
        //客户端,客户端只依赖于抽象类个抽象方法,不依赖具体实现,这样客户端就很稳定
        public class GameManager
        {
            Road road;
            Building building;
            Tunnel tunnel;
            Jungle jungle;
            AbstractFactory factory;
            public GameManager(AbstractFactory factory) 
            {
                this.factory = factory;
            }
            public void BulidFacilities() 
            {
                road = factory.CreateRoad();
                tunnel = factory.CreateTunnel();
                jungle = factory.CreateJungle();
                building = factory.CreateBuilding();
            }
            public void Run()
            {
                road.AAA(jungle);
                tunnel.DDD();
                building.CCC();
                jungle.BBB();
            }
        }
    
    
        public class APP
        {
            static void Mains()
            {
                GameManager game = new GameManager(new ModernFactory());
                game.Run();
            }
        }
    }
  • 相关阅读:
    struct pack unpack
    读书笔记 第四章&第五章
    The Sieve of Eratosthens(爱拉托逊斯筛选法)
    2013年3月百度之星A题
    2013年3月百度之星B题
    好句子
    BFS 与 DFS
    记录本
    HDU 2028 如何计算最小公倍数?
    HDU 2015 偶数求和 解题报告
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6426841.html
Copyright © 2011-2022 走看看