GenericFactoryMethod泛型工厂模式实现简单IOC功能

2019-05-25 18:37:58 浏览数 (1)

1、简介

泛型工厂理论上不算Gof23中设计模式之一,但是也算是一种非常好的设计模式,个人认为,废话不多说,先写个简单的抽象工厂,在写一个泛型工厂的例子来比较抽象和泛型的区别.

2、实战

还是房屋和道路,always road and house,例子不重要重要的是对模式的理解.

3、抽象工厂

代码语言:javascript复制
    public class Program
    {
        public static void Main(string[] args)
        {
            var build = new BuildSystem(new ModernFactory());
            build.Build();
            Console.ReadKey();
        }
    }

    /// <summary>
    /// 抽象道路
    /// </summary>
    public abstract class Road
    {
        /// <summary>
        /// 该抽象方法,没有实际意义,只为演示效果
        /// </summary>
        /// <returns></returns>
        public abstract string ShowMessage();
    }

    /// <summary>
    /// 现代化道路
    /// </summary>
    public class ModernRoad : Road
    {
        public override string ShowMessage()
        {
            return "I am Modern Road";
        }
    }

    /// <summary>
    /// 抽象房屋
    /// </summary>
    public abstract class House
    {
        /// <summary>
        /// 该抽象方法,没有实际意义,只为演示效果
        /// </summary>
        /// <returns></returns>
        public abstract string ShowMessage();
    }

    /// <summary>
    /// 现代化房屋
    /// </summary>
    public class ModernHouse : House
    {
        public override string ShowMessage()
        {
            return "I am Modern House";
        }
    }

    /// <summary>
    /// 前面的随笔中说过,抽象工厂是为了解决系列抽象对象的创建,所以里面会有>1个抽象对象的创建方法
    /// </summary>
    public abstract class AbstractFactory
    {
        public abstract Road CreateRoad();

        public abstract House CreateHouse();
    }

    /// <summary>
    /// 现代化房屋和道路的创建工厂
    /// </summary>
    public class ModernFactory : AbstractFactory
    {
        public override House CreateHouse()
        {
            return new ModernHouse();
        }

        public override Road CreateRoad()
        {
            return new ModernRoad();
        }
    }

    /// <summary>
    /// 构建系统
    /// </summary>
    public class BuildSystem
    {
        private AbstractFactory _abstractFactory;
        public BuildSystem(AbstractFactory abstractFactory)
        {
            _abstractFactory = abstractFactory;
        }

        public void Build()
        {
            var house=_abstractFactory.CreateHouse();
            var road=_abstractFactory.CreateRoad();
            Console.WriteLine($"{house.ShowMessage()},现已被创建");
            Console.WriteLine($"{road.ShowMessage()},现已被创建");
        }
    }

ok,简单的通过抽象工厂解决了现代化风格房屋的创建,且BuildSystem并没有依赖具体的现代化房屋和道路的实现,他依赖的是抽象,且如果这个时候需要其他风格的房屋和道路的创建,只需要通过扩展的方式依次添加抽线和具体的实现来完成需求.这里就不实现了,自行参考前面的随笔.

2、泛型工厂

下面来通过泛型工厂来实现上面的案例

代码语言:javascript复制
    public class Program
    {
        public static void Main(string[] args)
        {
            new BuildSystem().Build();
            Console.ReadKey();
        }
    }

    public abstract class Road
    {
        public abstract string ShowMessage();
    }

    public class ModernRoad : Road
    {
        public override string ShowMessage()
        {
            return "I am Modern Road";
        }
    }

    public class Factory<T> where T : class
    {
        public static T Get()
        {
            return _create.Create();
        }

        static ICreator _create;
        interface  ICreator
        {
            T Create();
        }

        class Creator<TChild> : ICreator where TChild:T,new()
        {
             public  T Create()
            {
                return new TChild();
            }
        }

        class SingletonCreator<TChild> : ICreator where TChild : T, new()
        {
            /// <summary>
            /// 初始化TChild的时候会调用static构造函数,所以线程安全.
            /// </summary>
            static readonly T Instance = new TChild();
            public T Create()
            {
                //这里单例可以使用双检锁创建单例对象,也可以使用"内联初始化"来创建单例对象
                return Instance;
            }
        }

        /// <summary>
        /// 支持继承关系的Set方法
        /// </summary>
        /// <typeparam name="TChild"></typeparam>
        public static void Set<TChild>() where TChild:T,new()
        {
            _create = new Creator<TChild>();
        }

        /// <summary>
        /// 支持单例同时支持继承的Set方法
        /// </summary>
        /// <typeparam name="TChild"></typeparam>
        public static void SetSingleton<TChild>() where TChild : T, new()
        {
            _create = new SingletonCreator<TChild>();
        }
    }
   
    /// <summary>
    /// 构建系统
    /// </summary>
    public class BuildSystem
    {

        public void Build()
        {
            //注册ModernRoad对象,Transiant模式
            Factory<Road>.Set<ModernRoad>();
            var r1=Factory<Road>.Get().GetHashCode();
            var r2= Factory<Road>.Get().GetHashCode();
            Console.WriteLine("r1和r2引用"   (ReferenceEquals(r1, r2) ? "相等" : "不相等"));

            //注册ModernRoad对象,单例模式
            Factory<Road>.SetSingleton<ModernRoad>();
            var s1 = Factory<Road>.Get();
            var s2 = Factory<Road>.Get();
            Console.WriteLine("s1和s2引用" (ReferenceEquals(s1, s2)?"相等":"不相等")); 
        }
 
    }

上面使用泛型工厂配合C#其他一些特性完成了一个简单版的IOC容器的功能.所以在设计一些模块的时候也可以考虑将泛型工厂作为创建型模式的一种选择方案.

当然你也可以进一步的扩展,通过一个字典类,来完成配置文件的方式,来动态的完成对象的注入,这里就不演示,自行实现.

0 人点赞