zoukankan      html  css  js  c++  java
  • 我对IOC控制反转,依赖注入原理的理解

    前提:

    什么是可扩展性良好的程序:在需求变更或需求增加时,不需要修改代码,而是增加代码的方式来适应需求的变化。

    现假设需要拍一个电影的场景:

    需要剧本(Screenplay),演员(Palyer),导演(Director)。

    导演按照剧本的流程,挑选演员去完成拍戏工作。

    1. 最一般,最直接的实现是这样写的:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text;
    
    namespace Com.DeepLeo.IOC.Normal 
    { 
    class Program 
    { 
       static void Main(string[] args) 
    { 
       Screenplay screenplay = new Screenplay(); 
       screenplay.Paly(); 
       Console.ReadKey(); 
    }
    
    /// <summary> 
    /// 剧本 
    /// </summary> 
    public class Screenplay 
    { 
       public string Name 
       { 
         private set; 
         get; 
        } 
       public Screenplay() 
       { 
         Name = "China"; 
       } 
       public void Paly() 
      { 
         Palyer palyer = new Palyer(); 
         palyer.Play("Play"); 
      } 
    }
    
    /// <summary> 
    /// 演员 
    /// </summary> 
    public class Palyer 
    { 
       public void Play(string mes) 
      { 
        Console.WriteLine(mes); 
       } 
     } 
    } 
    }
    

      

    这样写的不足:如果需要更换演员,需要重写剧本(Screenplay)或者直接更改Palyer类,也就是无法以最小的代码更改来达到需求变更的需要。这样需要修改大量代码,不是好的设计。


    2.对选择演员的“控制”反转给剧本:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text;
    
    namespace Com.DeepLeo.IOC.IndependenceRole 
    { 
      class Program 
      { 
        static void Main(string[] args) 
        {  
           Screenplay screenplay = new Screenplay(); 
           screenplay.Driver(); 
           Console.ReadKey(); 
        } 
        public class Screenplay 
       { 
          public string Name 
         {  
            private set; 
             get; 
          } 
          public Screenplay() 
          { 
             Name = "China"; 
          } 
          public void Driver() 
          { 
             Palyer palyer= new MoviePalyer(); 
             palyer.Play(); 
          } 
         } 
    public abstract class Palyer 
     { 
       public abstract void Play(); 
     } 
    public class MoviePalyer : Palyer 
    { 
      public override void Play() 
      { 
       Console.WriteLine("Paly a movie"); 
      } 
    } 
    public class TelePalyer : Palyer 
    { 
       public override void Play() 
       { 
         Console.WriteLine("Paly a teleplay"); 
       } 
     } 
    } 
    } 
    

      

    这个的好处是剧本可以选择演员了,想排成电影就用演电影的演员,想排成电视剧就用电视剧的演员。很好了降低了演员变更对剧本的影响。

    但是:在适应这个变化是以改剧本为代价的。有什么方法在换演员的时候不需要该剧本也可以达到同样的效果呢?

    3. 将更改剧本的“控制”反转给导演,由导演来决定。

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text;
    
    namespace Com.DeepLeo.IOC.IndependenceRole 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
               Director director = new Director(); 
               director.Drive(); 
               Console.ReadKey(); 
             } 
    public class Director 
    { 
        public Director() 
        { 
        } 
        public void Drive() 
        { 
           Palyer palyer = new MoviePalyer();//导演想拍电影 
           Screenplay screenplay = new Screenplay(palyer); 
           screenplay.Run(); 
        } 
    } 
    public class Screenplay 
    { 
        public Palyer Palyer 
        { 
           set; 
           get; 
         } 
         public string Name 
         { 
           private set; 
           get; 
         } 
         public Screenplay(Palyer palyer) 
         { 
            Palyer = palyer; 
            Name = "China"; 
         } 
         public void Run() 
         { 
            Palyer.Play(); 
         } 
    } 
    public abstract class Palyer 
    { 
        public abstract void Play(); 
    } 
    public class MoviePalyer : Palyer 
    { 
        public override void Play() 
       { 
          Console.WriteLine("Paly a movie"); 
       } 
    } 
    public class TelePalyer : Palyer 
    { 
        public override void Play() 
        { 
           Console.WriteLine("Paly a teleplay"); 
        } 
    } 
    } 
    }
    

      

    好处:不管你是改剧本还是改导演,只需要修改Director类就可以了,剧本和演员可以按照导演的喜好随意改。

    譬如:导演想拍电视剧版的:

    Palyer palyer = new TelePalyer (); 
    Screenplay screenplay = new Screenplay(palyer); 
    screenplay.Run();
    

      

    换剧本与换演员是一样的道理。

    当然,你也可以用接口实现IOC

    4.利用接口依赖注入,Screenplay 实现IInjectPalyer接口来注入,控制权还是在导演手中。

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text;
    
    namespace Com.DeepLeo.IOC.InterfaceInjectScreenplay 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
              Director director = new Director(); 
              director.Drive(); 
              Console.ReadKey(); 
             } 
    public interface IInjectPalyer 
    { 
         void InjectPalyer(Palyer palyer); 
    } 
    public class Director 
    { 
          public Director() 
          { 
          } 
    
          public void Drive() 
          { 
               Palyer palyer = new MoviePalyer(); 
               Screenplay screenplay = new Screenplay(); 
               screenplay.InjectPalyer(palyer); 
               screenplay.Run(); 
          } 
    } 
    public class Screenplay : IInjectPalyer 
    { 
         public Palyer Palyer 
         { 
             private set; 
             get; 
          } 
         public void InjectPalyer(Palyer palyer) 
          { 
             Palyer = palyer; 
          } 
         public string Name 
         { 
            private set; 
            get; 
          } 
          public Screenplay() 
          { 
             Name = "China"; 
          } 
          public void Run() 
          { 
             Palyer.Play(); 
          } 
    } 
    public abstract class Palyer 
    { 
         public abstract void Play(); 
    } 
    public class MoviePalyer : Palyer 
    { 
          public override void Play() 
         { 
             Console.WriteLine("Paly a movie"); 
         } 
    } 
    public class TelePalyer : Palyer 
    { 
         public override void Play() 
         { 
          Console.WriteLine("Paly a teleplay"); 
         } 
    } 
    } 
    }
    

      

    以上仅仅是我对IOC概念的理解,希望对大家有所帮助。

     转自:http://www.deepleo.com/archives/782

    源代码:https://files.cnblogs.com/deepleo/IOC.zip

  • 相关阅读:
    C++
    Qt简介
    C语言
    C/C++
    swagger2 Illegal DefaultValue null for parameter type integer
    maven包引入问题ClassNotFoundException: org.elasticsearch.client.Cancellable
    mysql自定义排序
    使用node创建服务器 运行vue打包的文件
    rsync实现服务器之间同步目录文件
    将jar包发布到maven的中央仓库细节整理
  • 原文地址:https://www.cnblogs.com/deepleo/p/ioc_mysample.html
Copyright © 2011-2022 走看看