zoukankan      html  css  js  c++  java
  • 依赖注入(一)工厂

    依赖注入(一)工厂

       许多时候我想等我把某些问题,完全想明白,完全理解透,再写点东西;事实往往相反,发现等我真正接近,把某些东西理解好,我自己再也不屑写点东西分享了,没有精神气也好,不着调也好,这对于我的性格至少是一个事实。懂得越多的人或理解的越深的时候,人越容易沉默;半调子的时候我一直在叫嚣,就像现在的我。

       决定改变方式,不要等想好了再动笔,也不要等完全弄明白了再动笔,看点写点。

    小马过河,亲自走一走就会知道。

           “不要信我,否则你死得很惨!”

    做事,不能只想。现在的我喜欢做,只需要想个清晰的目标就可以。

    人想进步 就是不满足于现状,想把好东西投入生产就需要一点一滴的积累,做好技术的沉淀吧,这样面对高一点的层次时,也能游刃有余。

    跑题了。下面开始举个栗子。在网上抄的,但很能说明问题。这里就让这段话来引入吧。

    现实世界中,会有这么一种情况。

    比如,汽车不会强依赖于某个品牌的轮胎,任何公司生产的轮胎,只要符合汽车的接口,就可以装在这个汽车上使用。

    还有电脑的USB接口,只要符合USB标准的外设,就都能够接上电脑使用。

    面向对象编程也是如此。

    那到底什么是依赖注入呢?依赖注入(Dependency Injection)。简称DI,它还有另外一个名字,控制反转(Inversion of Control,英文缩写为IoC)。

       当某个角色(可能是一个实例,调用者)需要另一个角色(另一个实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在依赖注入里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由依赖注入容器来完成,然后注入调用者,因此也称为依赖注入。

    用了些专业术语,有点高端大气上档次的感觉,我觉得其实就是抽象工厂,类似数据库抽象工厂DataAccess类(抽象工厂模式创建DAL)。

    下面给出DataAccess类实现。需要配置web.config和加一个Cache包装类。

     1 public sealed class DataAccess<T>
     3 {
     5     private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["WebDAL"];
     7     /// <summary>
     9     /// 创建对象或从缓存获取
    11     /// </summary>
    13     public static object CreateObject(string path, string CacheKey)
    15     {
    17         object objType = DataCache.GetCache(CacheKey);//从缓存读取
    19         if (objType == null)
           {
             try 25 { 27 objType = Assembly.Load(path).CreateInstance(CacheKey);//反射创建 29 DataCache.SetCache(CacheKey, objType);// 写入缓存 31 } 33 catch 35 { } 37 } 39 return objType; 41 } 42 43 /// <summary> 44 45 /// 根据配置文件生成一个传入的对象,并将其转为IDAL.IDAL泛型接口 46 47 /// </summary> 48 49 public static IDAL<T> GetIDAL(String Obj) 50 51 { 52 53 string CacheKey = path + "." + Obj; 54 55 object objType = CreateObject(path, CacheKey); 56 57 return (IDAL<T>)objType; 58 59 } 60 61 /// <summary> 62 63 /// 创建非IDAL接口的数据层接口 64 65 /// </summary> 66 67 public static T CreateDAL(String Obj) 68 69 { 70 71 string CacheKey = path + "." + Obj; 72 73 object objType = CreateObject(path, CacheKey); 74 75 return (T)objType; 76 77 } 78 79 }

    上面又有点跑题的感觉。下面给出一个简单例子对比一下,体现出控制反转。

    ChineseMan 有2个方法

     1 public class ChineseMan
     3 {
     5     public void Say()
     7     {
     9         Console.WriteLine("中文");
    11     }
    13     public void Sex()
    15     {
    17         Console.WriteLine("");
    19     }
    23  }

    使用

     class Program
     {
         static void Main(string[] args)
         {
              ChineseMan cm =new ChineseMan();// 改变这里
              cm.Say(); 
              cm.Sex(); 
         } 
     }

    当加入另一个人时就会出现

    EnglishMan

     1 public class EnglishMan
     3 {
     5     public void Say()
     7     {
     9         Console.WriteLine("English");
    11     }
    13     public void Sex()
    15     {
    17         Console.WriteLine("male");
    19     }
    20  }
    class Program
    {
        static void Main(string[] args)
        {
            EnglishMan em=new EnglishMan();// 改变这里
            em.Say();
            em.Sex();
         }
    }    

    使用多态

    //接口
    public
    interface IPeople { void Say(); void Sex(); }
    //继承接口
    public class ChineseMan : IPeople { public void Say() { Console.WriteLine("中文"); } public void Sex() { Console.WriteLine(""); } } public class EnglishMan : IPeople { public void Say() { Console.WriteLine("English"); } public void Sex() { Console.WriteLine("male"); } } static void Main(string[] args) {
       //多态 IPeople pe
    = new ChineseMan(); pe.Say(); pe.Sex(); pe = new EnglishMan(); pe.Say(); pe.Sex(); }

    使用工厂。

    类还是上面多态中的。

    工厂类

    public class Factory
    {
        public static IPeople GetPeople()
        {
            return new ChineseMan();//需要ChineseMan new ChineseMan()  需要EnglishMan new English()
        }
    }
    static void Main(string[] args)
    {
        IPeople pe = Factory.GetPeople();
        pe.Say();
        pe.Sex();
     }

    有人说,这不是还得在 Factory类中换需要new的具体类? 是的 但是在变化时Main方法却不需要重新编译,当有类似ChineseMan 类新加时只需要加类比如 ChineseWoman 类,只需加类并且 只改变Factory 类,Factory类做的再好点,就加反射。

    public static IPeople GetPeople()
    {
        object obj = Assembly.Load("IoCDemo").CreateInstance("IoCDemo.EnglishMan");//IoCDemo是namespace  namespace IoCDemo
        return obj as IPeople;//需要ChineseMan new ChineseMan()  需要EnglishMan new English()
    }

    IoCDemo IoCDemo.EnglishMan 这两个字符串可通过XML获得 在外部进行配置。这样就完全不需要改,只需要加类就行了。

    下一篇介绍第三方依赖注入容器。

       解除依赖不仅让代码结构看起来更加合理,其带来的另一个好处是,各个部分可以单独的做单元测试,使得单元测试能够更加容易的进行。这个对于一些复杂度高的项目,对于保证项目的稳定性和可用性非常有意义。

  • 相关阅读:
    SQL优化
    Mybatis
    Spring MVC(总结二)
    ES多机集群配置
    ES索引,分片,一致性
    ElasticSearch关于索引库的命令操作
    试题01(一)
    Linux安装配置elastic search
    Windows安装配置elastic search
    SpringBoot(二)
  • 原文地址:https://www.cnblogs.com/chengjunchao/p/3684038.html
Copyright © 2011-2022 走看看