专栏首页GreenLeavesGenericFactoryMethod泛型工厂模式实现简单IOC功能

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

1、简介

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

2、实战

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

3、抽象工厂

    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、泛型工厂

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

    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 条评论
登录 后参与评论

相关文章

  • .Net 从零开始构建一个框架之基本实体结构与基本仓储构建

    本系列文章将介绍如何在.Net框架下,从零开始搭建一个完成CRUD的Framework,该Framework将具备以下功能,基本实体结构(基于DDD)、基本仓储...

    郑小超.
  • C# Command命令(行为型模式)+队列 实现事务,带异步命令重试机制和生命周期

    耦合是软件不能抵御变变化的根本性原因,不仅实体对象与实体对象之间有耦合关系(如创建性设计模式存在的原因),对象和行为之间也存在耦合关系.

    郑小超.
  • FactoryMethod工厂方法模式(创建型模式)

    整个抽象的游戏设施建造系统相对变化较慢,本例中只有一个Build的创建方法,而Build内部的方法实现,该实现依赖与各种具体的实现,而这些实现变化的非常频繁,现...

    郑小超.
  • Magicodes.IE之Excel模板导出教材订购表

    本教程主要说明如果使用Magicodes.IE.Excel完成教材订购表的Excel模板导出。

    雪雁-心莱科技
  • C# http Get/POST请求封装类

    http://www.sufeinet.com/thread-3-1-1.html

    跟着阿笨一起玩NET
  • Magicodes.WeiChat——发送模板消息

    在微信开发中,经常会使用到模板消息。因此框架中对此进行了一些封装,并且提供了后台操作界面以及日志查看等功能,下面开始逐步介绍开发操作以及使用。

    雪雁-心莱科技
  • Excel模板导出之导出教材订购表

    本教程主要说明如果使用Magicodes.IE.Excel完成教材订购表的Excel模板导出。

    心莱科技雪雁
  • (Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)

    应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容...

    菩提树下的杨过
  • HashSet底层分析

    对于HashSet而言,它是基于HashMap实现的。HashSet底层采用HashMap来保存元素,因此HashSet底层其实比较简单。

    用户6182664
  • JDK1.8源码(八)——java.util.HashSet 类

      在上一篇博客,我们介绍了 Map 集合的一种典型实现  HashMap  ,在 JDK1.8 中,HashMap 是由 数组+链表+红黑树构成,相对于早期版...

    IT可乐

扫码关注云+社区

领取腾讯云代金券