zoukankan      html  css  js  c++  java
  • 控制反转 IOC 与依赖注入 DI

      今天在学习过程中,有一个接触到IOC 。.netCore中已经帮助开发者实现了IOC 例如:

     
     public class HomeController : Controller
        {
            private ILogger _Logger;
    
            public HomeController(ILogger logger)  //依赖于抽象,具体细节的实现在IOC容器中实现
            {
                _Logger = logger;
            }
            public IActionResult Index()
            {
                _Logger.LogWarning("测试logger 警告");
                return View();
            }
    }
     
    //注:如果是自定义的类或者扩展的类,同时要在StartUp的 ConfigureServices方法中注册一下,才能够使用。

    在学习之前先了解几个概念

    DIP           依赖倒置原则
    IOC          控制反转(是一种思想)
    DI             依赖注入 实现IOC的一种手段
    IOC容器   依赖注入的框架,用来映射依赖 ,管理对象创建和生命周期

    那什么是依赖呢?通俗的讲,就是用到的地方。系统中一个类使用了另一个类是非常常见的现象。所以我们不可能完全脱离依赖。

    例如在下面的案例中:

    public class Person
        {
            public void Speack()
            {
                var china = new ChinaLanguage();
                china.SayHi("小小");
                china.SayBack();
            }
        }
    
    
        public class ChinaLanguage
        {
            public string SayHi(string name)
            {
                return $"你好,我是{name}";
            }
    
            public string SayBack()
            {
                return "我要先离开了";
            }
        }
    
    
    
    
     public class EnglishLanguage
        {
            public string SayHi(string name)
            {
                return $"hello,I'm{name}";
            }
    
            public string SayBack()
            {
                return "I'll back";
            }
        }

     public class Main
        {
    
          public void Excute()
            {
                var person = new Person();
                person.Speack();
            }
        }


     如果我要改成英文版,我就要把Speack 方法修改为如下:

     
     public void Speack()
            {
                var englishPerson = new EnglishLanguage();
                englishPerson.SayHi("小小");
                englishPerson.SayBack();
            }
    
     

     如果项目中海油很多地方要使用,我们这样改起来的工作量比较大,组件之间高度耦合,可扩展性较差,它违背了DIP原则。即高层模块 Person类,不应该依赖于ChinaSpeack类。下面就看一下依赖倒置原则:

    依赖倒置原则:   

    • 1. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。  
    • 2. 抽象不能依赖于具象,具象依赖于抽象。

    按照上面的规则,我们应该将Person 依赖于抽象,而不是具体细节。修改如下:

     
       
    
        public class Person
        {
            private ILanguage _personSpeack;
    
            public Person(ILanguage personSpeack)
            {
                _personSpeack = personSpeack;
            }
    
            public void Speack()
            {
                //var china = new ChinaLanguage();
                //china.SayHi("小小");
                //china.SayBack();
                _personSpeack.SayHi("小小");
                _personSpeack.SayBack();
            }
        }
    
        public interface ILanguage
        {
            string SayHi(string name);
    
            string SayBack();
        }
    
        public class ChinaLanguage:ILanguage
        {
            public string SayHi(string name)
            {
                return $"你好,我是{name}";
            }
    
            public string SayBack()
            {
                return "我要先离开了";
            }
        }
    
    //调用 public class Main { public void Excute() { var person = new Person(new ChinaLanguage()); //具体细节在外部实现,而不是在类内部调用 person.Speack(); } }

     这样看来,就把依赖对象的创建和绑定转移到被依赖对象类的外部来实现了。这样就实现了控制反转。(获得依赖对象的过程被反转了)

    依赖注入的实现方法有三种:

    构造函数注入,属性注入和接口注入。上面的案例就是构造函数注入。

    讲了这么说的原理,下面稍微记录一下IOC的缺点,毕竟没有完美的框架嘛

    1.首先在开发的过程中,会需要凭空多很多的接口开发。对于开发而言增加了工作量。

    2.IOC 通过反射的方式运行的,在性能上会有一定的损耗。

    参考文档: https://blog.csdn.net/ivan820819/article/details/79744797

    https://www.cnblogs.com/liuhaorain/p/3747470.html

  • 相关阅读:
    sping AOP核心思想及实现原理
    springmvc RequestMappingHandlerMapping初始化详解
    springmvc RequestMappingHandlerAdapter初始化详解
    POJ 3169 Layout
    POJ 3264
    POJ 3461 Oulipo
    二分图判定 POJ-2492
    最小生成树 prim算法
    初级BFS
    哈夫曼建树
  • 原文地址:https://www.cnblogs.com/kekelele/p/14601641.html
Copyright © 2011-2022 走看看