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();
            }
        }
    }
  • 相关阅读:
    DGA域名可以是色情网站域名
    使用cloudflare加速你的网站隐藏你的网站IP
    167. Two Sum II
    leetcode 563. Binary Tree Tilt
    python 多线程
    leetcode 404. Sum of Left Leaves
    leetcode 100. Same Tree
    leetcode 383. Ransom Note
    leetcode 122. Best Time to Buy and Sell Stock II
    天津Uber优步司机奖励政策(12月28日到12月29日)
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6426841.html
Copyright © 2011-2022 走看看