zoukankan      html  css  js  c++  java
  • IOC和DI之刨根问底 -- 第一节

    很多freshman上来就想搞清楚什么是IOC和DI,其实很多先进的理论和技术都在老的基础上升华出来的,最终目的是为了解放生产力。

    所以先来说说下面两点基础知识:

    • Direct Dependency(直接依赖)
    • Inverted Dependency(反向依赖)

    Direct Dependency

    应用程序中的依赖关系方向应该是抽象的方向,而不是实现详细信息的方向。 大部分应用程序都是这样编写的:编译时依赖关系顺着运行时执行的方向流动,从而生成一个直接依赖项关系图。 也就是说,如果类 A 调用类 B 的方法,类 B 调用 C 类的方法,则在编译时,类 A 将取决于类 B,而 B 类又取决于类 C,如图1所示。

     直接依赖项关系图

    假设一个A通过朋友B和C找超级富婆的故事,A只有B朋友的关系,B只有C朋友的关系,C朋友才能帮忙找到超级富婆!条件是“身体好”!

    对应的代码块如下:

      public class ClassA
        {
            /// <summary>
            /// Find super rich woman
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman()
            {
                var criteria = "身体好";
                return new ClassB().FindRichWoman(citeria);
            }
        }
       public class ClassB
        {
            /// <summary>
            /// Find super rich woman by citeria.
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman(string criteria)
            {return new ClassC().FindRichWoman(criteria);
            }
        }
       public class ClassC
        {
            /// <summary>
            /// Find super rich woman by criteria.
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman(string criteria)
            {
                if (criteria.Equals("身体好"))
                    return "Super Rich Woman";
    
                return string.Empty;
            }
        }

    编译时和运行时的依赖关系和控制关系都是A=》B=》C

    •  高层次类对底层次类正向依赖 - A要想找到富婆就必须要找到B,B需要去找C
    •  高层次类对低层次类的正向控制 - B什么时候要富婆由A来决定,C什么时候去找富婆由B来决定

    Inverted Dependency

    应用依赖关系反转原则后,A 可以调用 B 实现的抽象上的方法,让 A 可以在运行时调用 B,而 B 又在编译时依赖于 A 控制的接口(因此,典型的编译时依赖项发生反转)。 运行时,程序执行的流程保持不变,但接口引入意味着可以轻松插入这些接口的不同实现。

    反转依赖项关系图

    • 依赖关系反转原则之抽象接口和工厂模式应用 - 上面那段话可以这么理解,A发现找个富婆还要自己亲自去找B,还得管B的吃喝拉撒,所以是否可以找机器人中心(工厂模式)帮忙搭线,自己只要找到由B抽象出来的虚拟机器人就可以了

     使用工厂模式后,只需要将抽象接口B给到工厂就能找到想要的方法,A不用去关注对象B是怎么产生的。

      public class ClassA
        {
            /// <summary>
            /// Find super rich woman
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman()
            {
                var criteria = "身体好";
                return factory.CreateInstance(InterfaceB).FindRichWomanByB(criteria);
            }
        }
    •    接口引入意味着可以轻松插入这些接口的不同实现 如果A突然不想通过B找富婆,假设D也不需要任何条件就可以现实找到富婆,那A肯定很乐意换成通过D,我只需要把InterfaceB换成InterfaceD丢给工厂。
       public class ClassD: InterfaceD
        {
            /// <summary>
            /// Find super rich woman
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman()
            {
               return "Super Rich Woman";
            }
        }
    }
      public class ClassA
        {
            /// <summary>
            /// Find super rich woman
            /// </summary>
            /// <returns>return super rich woman</returns>
            public string FindRichWoman()
            {
                return factory.CreateInstance(InterfaceD).FindRichWoman(); 
         }
       }

     发现很多博主在讲解IOC时,就将此处的概念就定义为IOC, 其实此处:

    •  高层次的类不再正向依赖于低层次的类,两者都依赖于抽象接口  - 类A和类B依赖了InterfaceB
    •  低层次类依赖于高层次类的需求抽象 类A有找富婆的需求,那么低层次抽象出来的InterfaceB和InterfaceD都有实现找富婆的办法,所以他们就都有依赖于来自高层次类A抽象出来找富婆的需求

    最大的优势就是解耦了高层次模块对于低层次模块的紧密依赖,可以灵活扩展!

    到了锻炼身体的时间了,下一节再来说IOC和DI的概念和对应的场景


    海的呐喊
  • 相关阅读:
    天乙社区后台管理分析(一)
    [Android Webkit]JNI基础及Java层与C++层的交互
    1033
    pat 1049. Counting Ones (30)
    juce: 跨平台的C++用户界面库
    高性能MySql进化论(一):数据类型的优化_上
    url参数中有+、空格、=、%、&、#等特殊符号的处理
    带环单链表的问题
    在SQL Server 中启用 FileStream
    (2)入门指南——(2)jQuery可以做什么(What jQuery does)
  • 原文地址:https://www.cnblogs.com/kejie/p/15478095.html
Copyright © 2011-2022 走看看