IoC控制反转设计原则——实现松耦合

  • 1.IoC设计原则
    • 1.1.控制程序流
    • 1.2.控制依赖对象的创建
  • 2.从典型的n层体系架构来理解IoC

IOC是一种设计原则(虽然,有很多人将它当成是一种设计模式),不是设计模式。它提供了高层级的设计指南,但不提供实现细节。意味着你可以自由实现IoC原则。

1.IoC设计原则

正如IOC(控制的反转)的名字一样,IoC被用来反转不同类型的控制在面向对象设计中获得松耦合。这里的控制指的是类拥有的除了主要职责的其他的职责。这包括对应用程序流的控制,对象创建或依赖的对象创建绑定的流的控制。

打个比方说,你开车去上班,意味着你控制着车。IOC原则则建议你反转控制,意味着不是你自己开车,你可以租一辆出租车,让另外一个人来开,这就是所谓的控制反转,这样一来,你就不用再管控制车的任何操作,让司机去控制,你就可以专心做自己的事了。

IoC原则帮助设计松耦合的类,使得这些类可测试、可维护和可扩展。让我们来理解一下Ioc是怎样返回不同种类的控制的。

1.1.控制程序流

如Java的典型应用,从main()函数开始执行的。main()函数控制了程序的流程,或者换句话说,是用户交互的顺序。

class Program{static void Main(string[] args){bool continueExecution = true;do{Console.Write("Enter First Name:");var firstName = Console.ReadLine();Console.Write("Enter Last Name:");var lastName = Console.ReadLine();Console.Write("Do you want to save it? Y/N: ");var wantToSave = Console.ReadLine();if (wantToSave.ToUpper() == "Y")SaveToDB(firstName, lastName);Console.Write("Do you want to exit? Y/N: ");var wantToExit = Console.ReadLine();if (wantToExit.ToUpper() == "Y")continueExecution = false;}while (continueExecution);}private static void SaveToDB(String firstName, String lastName){//save firstName and lastName to the database here..}}

1.2.控制依赖对象的创建

IoC也可以应用到创建依赖类的对象。什么是依赖呢?

public class A
{B b;public A(){b = new B();}public void Task1() {// do something here..b.SomeMethod();// do something here..}}public class B {public void SomeMethod() { //doing something..}
}

在上面这个例子中,A调用b.SomeMethod()来完成它的task1。如果没有B类的对象,A类不能够完成它的任务。因此,我们可以说“A类依赖于B类”或者“B类是A类的依赖”。

在面向对象设计的方法中,类需要互相交互才能完成一个或多个应用程序的功能。例如上面的例子,A类创建并管理B类的对象的生命周期。本质上,A类控制依赖类的对象的创建和生存时间。IoC原则建议反转控制,这意味着将控制委托给另一个类。 换句话说,就是把A的依赖关系创建的控制反转给另一个类来做,如下所示:

public class A
{B b;public A(){b = Factory.GetObjectOfB();}public void Task1() {// do something here..b.SomeMethod();// do something here..}
}public class Factory
{public static B GetObjectOfB() {return new B();}
}

如你所见,A使用了工厂类来获得B类的对象。因此,我们把依赖对象的创建从A类反转到了一个工厂类里。A类不再负责创建B类的对象。取而代之的是A类将使用工厂类来获取B类的对象。

在面向对象设计中,类应该被设计成松耦合的。松耦合意味着一个类里的变化不应该强制其他类也跟着变化。所以这样一来,整个应用变得可维护和可扩展。

2.从典型的n层体系架构来理解IoC

我们再从典型的n层体系架构来理解IoC。

在典型的n层体系架构里,UI(User Interface)使用Service层来获取和保存数据;而Service层使用BusinessLogic类来对数据应用业务规则;BusinessLogic类依赖DataAccess类,DataAccess类是用来检索数据或将数据保存底层数据库的。

public class CustomerBusinessLogic
{DataAccess _dataAccess;public CustomerBusinessLogic(){_dataAccess = new DataAccess();}IoC is a principle, not a pattern. It just gives high-level design guidelines but does not give implementation details. You are free to implement the IoC principle the way you want.public string GetCustomerName(int id){return _dataAccess.GetCustomerName(id);}
}public class DataAccess
{public DataAccess(){}public string GetCustomerName(int id) {return "Dummy Customer Name"; // get it from DB in real app}
}

正如你所见,CustomerBusinessLogic类依赖于DataAccess类,它创建DataAccess类的对象并用来获得customer的数据。CustomerBusinessLogic不仅要负责创建DataAccess类的对象,还要管理其生命周期。CustomerBusinessLogic类和DataAccess类紧耦合在一起。这样的设计会有以下这些问题:

  • 当DataAccess类有变化就会导致CustomerBusinessLogic也要跟着改,例如,我们添加、删除或重命名DataAccess类里的任何方法,我们都要相应地修改CustomerBusinessLogic类。
  • 假设customer的数据来自不同的数据库或web services,并且在将来我们可能需要创建不同的类等,都会导致CustomerBusinessLogic类要做相应的修改。
  • CustomerBusinessLogic类使用new关键创建DataAccess类对象,可能有多个类使用DataAccess类和创建它的对象。所以当修改DataAccess的类名,你就需要找出所有使用DataAccess类的地方,并做相应修改。这些都是用于创建相同类的对象并维护其依赖关系的重复性代码。
  • 因为CustomerBusinessLogic类创建一个具体的DataAccess类对象,使用它不能够独立测试,因为DataAccess类不能够用模拟类来代替。

为了解决以上这些问题,获得松耦合设计,我们可以使用IoC和DIP原则共同来解决。IoC是一种设计原则,不是一种设计模式,它指提供高层设计指南,不提供实现细节。你可以自由地使用自己的方式去实现这一原则。以下设计模式(但不限于)都实现了IoC原则:

我们用工厂模式(Factory)来实现IoC,首先创建一个工厂类,它负责返回DataAccess类:

public class DataAccessFactory
{public static DataAccess GetDataAccessObj() {return new DataAccess();}
}

接着,使用DataAccessFactory类在CustomerBusinessLogic类里获得DataAccess类的对象:

public class CustomerBusinessLogic
{public CustomerBusinessLogic(){}public string GetCustomerName(int id){DataAccess _dataAccess =  DataAccessFactory.GetDataAccessObj();return _dataAccess.GetCustomerName(id);}
}

正如你所见,CustomerBusinessLogic类使用DataAccessFactory.GetCustomerDataAccessObj()方法获得DataAccess类的对象,而不是用new关键字创建它。因此,我们反转了CustomerBusinessLogic类依赖的DataAccess类的对象的创建的控制,通过DataAccessFactory工厂类。
与IoC一起,我们也可以用DIP原则, Strategy设计模式和依整注入DI(Dependency Injection)来一起用出以获得松耦合。

IoC控制反转设计原则——实现松耦合相关推荐

  1. DIP依赖反转原则——实现松耦合的设计

    在<IoC控制反转设计原则--实现松耦合>我们将控制工作委派给其他类来完成,向松耦合设计又迈进了一步.但是我们类仍然依赖着具体的类,所以我们可以使用DIP(依赖反转原则)来进一步获得松耦合 ...

  2. 控制反转_Spring:IOC 控制反转

    Spring 概述 Spring 是什么 Spring 是分层的 Java SE/EE 应用 full-stack (全栈式) 轻量级开源框架. 全栈式:对各种主流技术和框架都进行了整合,同时对三层架 ...

  3. 06_02_Spring 任务一:IOC控制反转

    任务一课程主要内容: spring概念介绍 IOC spring快速入门 spring相关API介绍 Spring配置文件 DBUtils spring注解开发 spring整合Junit 一 Spr ...

  4. Spring框架中IoC(控制反转)的原理

    一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.即软件系统中对象之间的耦合,对 ...

  5. 什么是IOC(控制反转)、DI(依赖注入)举个形象的例子通俗易懂

    更多免费教学文章请关注这里 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清 ...

  6. 什么是IOC(控制反转)、DI(依赖注入)

    原文地址(摘要了部分内容):https://blog.csdn.net/qq_22654611/article/details/52606960/ 学习过Spring框架的人一定都会听过Spring的 ...

  7. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...

  8. 详解spring的IOC控制反转和DI依赖注入

    转载 详解spring的IOC控制反转和DI依赖注入 2018-06-05 15:45:34 jiuqijack 阅读数 2945 文章标签: spring IOC控制反转 DI依赖注入 更多 分类专 ...

  9. Spring的IOC(控制反转)与DI(依赖注入)

    Spring控制反转与依赖注入 文章目录 Spring控制反转与依赖注入 1. 控制反转(IOC) 2. 依赖注入(DI) 3. 总结 1. 控制反转(IOC) 控制反转(Inversion of C ...

最新文章

  1. 公钥密码--Paillier
  2. sitecore系统教程之体验编辑器
  3. c mysql 并发处理_mysql队列中实现并发读的实现方法解析
  4. ❤️使用Spring注解开发(建议收藏)
  5. Lingo软件的使用
  6. 项目实施计划及总体设计报告(大纲)
  7. 维纶触摸屏程序实际项目,威纶通界面UI
  8. React-native学习-59:使用react-native-vector-icons图标库
  9. “程序已停止工作”问题的解决方法,停止解决方法
  10. php 公众号指定人发消息,微信公众号发送模板消息,发送消息到某个用户
  11. 为所欲为表情包制作器
  12. 纯前端支持拼音搜索功能
  13. HTML图片鼠标滑动加边框,鼠标移动到图片上时,用css怎么实现图片加边框效果?...
  14. UiPath Excel 复制粘贴
  15. zhu hao shi de shi
  16. 移植fastboot到2440
  17. 【精读笔记】JavaScript高级程序设计 第3章 语言基础
  18. 【Linux4.1.12源码分析】协议栈gro收包之TCP处理
  19. MacOS : 大前端必备姿势(工作环境)
  20. XML学习笔记——XSL

热门文章

  1. Flex AIR应用的启动闪屏(必须)
  2. 服务器显示以下错误,为通用Excel服务器配置安装SQL2008时,提示“SQL Server安装程序遇到以下错误,错误代码0x84B20001”...
  3. AS连接网易Mumu模拟器
  4. [附源码]java+ssm计算机毕业设计拼车平台0k47u(源码+程序+数据库+部署)
  5. python Flask 学前班
  6. minecraft java版多少钱_Java版版本记录
  7. 【英语:基础进阶_新闻美剧听说】G4.听力进阶—如何理解英美剧中的文化梗
  8. Git回滚版本并push到远端master
  9. Java证书哪个含金量高?
  10. 假设无线打印服务器,如何给我的usb接口的打印机改装成通过wifi连接的打印机...