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

  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/deepleo/p/ioc_mysample.html
Copyright © 2011-2022 走看看