• Inversion of Control


        Castle 的核心概念是 IoC, IoC 的抽象概念是”依赖倒置”,像是“高层模块不应该依赖低层模块,而是模块都必须依赖于抽象”是 IoC 的一种表现,“实现必须依赖抽象,而不是抽象依赖实现”也是 IoC 的一种表现,“应用程序不应依赖于容器,而是容器服务于应用程序”也是 IoC 的一种表现。 IoC 全名 Inversion of Control,如果中文硬要翻译过来的话,就是“控制反转”。初看 IoC,从字面上不容易了解其意义,我觉得要了解 IoC,要先从 Dependency Inversion 开始了解,也就是依赖关系的反转。
    Dependency Inversion The Dependency Inversion Principle有清楚的解释。

    简单的说,在模块设计时,高层的抽象模块通常是与业务相关的模块,它应该具有重用性,而不依赖于低层的具体模块,例如如果低层模块原先是软盘存取模式,而高层模块是个存盘备份的需求,如果高层模块直接调用低层模块的函数,则就对低层模块产生了依赖关系。

    举个例子,例如下面这个c程序:

    #include   

    void save() 
            
            saveToFloppy() 
        }




    由于save()程序依赖于依赖于saveToFloppy(),如果今天要更换低层的存储模块为Usb硬盘,则这个程序没有办法重用,必须加以修改才行,低层模块的更动造成了高层模块也必须跟着改动,这不是一个好的设计方式,在设计上希望模块都依赖于模块的抽象,这样才可以重用高层的业务设计。 如果以面向对象的方式来设计,依赖倒置(Dependency Inversion)的解释变为程序不应依赖实现,而是依赖于抽象,实现必须依赖于抽象。来看看下面这个 .NET 程序:
     
    public class BusinessObject 
        
    private FloppyWriter writer = new FloppyWriter(); 
        
        
        
    public void Save() 
             
            writer.SaveToFloppy(); 

        }

    }
     

    在这个程序中,BusinessObject 的存盘依赖于实际的 FloppyWriter,如果今天想要将存盘改为存至 Usb 硬盘,则必须修改或继承 BusinessObject 进行扩展,而无法直接使用BusinessObject。

    如果透过接口的声明,可以改进此一情况,例如:
    public interface IDeviceWriter 
        
    public void SaveToDevice(); 
    }
     

    public class BusinessObject 
        
    private IDeviceWriter writer; 

        
    public DeviceWriter
        
    {
          Set
          
    {
              
    this.writer = value; 
          }

        }
     

        
    public void Save() 
            
            writer.SaveToDevice(); 
        }

    }
     

    这样一来,BusinessObject 就是可重用的,如果今天有存储至 Floppy 或 Usb 硬盘的需求,只要实现 IDeviceWriter 即可,而不用修改 BusinessObject:
    public class FloppyWriter :IDeviceWriter 
        
    public void SaveToDevice() 
            
            
    // 实现储存至Floppy的程序代码 
        }
     
    }
     

    public class UsbDiskWriter : IDeviceWriter 
        
    public void SaveToDevice() 
            
            
    // 实现储存至UsbDisk的程序代码 
        }

    }
     

    从这个角度来看,Dependency Inversion 的意思就是程序不依赖于具体实现,而是程序与实现都要依赖于抽象。 IoC 的 Control 是控制的意思,其实其背后的意义也是一种依赖关系的转移,如果A依赖于B,其意义即是B拥有控制权,您想要转移这种关系,所以依赖关系的反转即是控制关系的反转,藉由控制关系的转移,可以获得组件的可重用性,在上面的 .NET 程序中,整个控制权从实际的 FloppyWriter 转移到抽象的 IDeviceWriter 接口上,使得BusinessObject、FloppyWriter、UsbDiskWriter 这几个实现依赖于抽象的 IDeviceWriter 接口。

    程序的业务逻辑部份应该是可以重用的,不应受到所使用框架或容器的影响,因为可能转移整个业务逻辑至其它的框架或容器,如果业务逻辑过于依赖容器,则转移至其它的框架或容器时,就会发生困难。

    IoC 在容器的角度,可以用这么一句好莱坞名言来代表:"Don't call me, I'll call you." 以程序的术语来说的话,就是“不要向容器要求您所需要的(对象)资源,容器会自动将这些对象给您!”。IoC 要求的是容器不侵入应用程序本身,应用程序本身提供好接口,容器可以透过这些接口将所需的资源注入到程序中,应用程序不向容器主动要求资源,故而不会依赖于容器的组件,应用程序本身不会意识到正被容器使用,可以随时从容器中脱离转移而不用作任何的修改,而这个特性正是一些业务逻辑中间件最需要的。
  • 相关阅读:
    C#ActiveX控件开发学习
    SPFA最短路算法
    用宏实现C/C++从非零整数开始的数组
    mysql学习笔记
    python学习笔记(多进程并发)
    python学习笔记(socket模块)
    jQuery学习笔记
    python学习笔记(IO模型)
    Django学习笔记
    导入Excel时启动Excel.exe进程出错
  • 原文地址:https://www.cnblogs.com/Jebel/p/1219187.html
Copyright © 2020-2023  润新知