java中的耦合与Spring IOC实现解耦

耦合

在软件工程中,对象之间的耦合度就是对象之间的依赖性。对象之间的耦合越高,即代表对象之间的依赖性很强,维护成本越高,因此对象的设计应使类和构件之间的耦合最小(高内聚低耦合),耦合在java中指的是,两个类之间的联系的紧密程度。

我们先来看一个例子:
在这里插入图片描述
这个例子中A类的方法参数使用到了B类,即A类依赖于B类,这是一种很强的耦合关系,因为A类的ATest方法只能使用B类,不能使用其它类了,另外,如果没有了B类,那么A类连编译都无法通过,这就是两个类耦合度很强的体现,我们在编程中应尽量少使用这种方式。

再看下面这个例子:
在这里插入图片描述
这个例子使用了面向接口编程,C类 与 A类、B类之间存在的是一种弱耦合关系,C类 的 put方法 的参数可以是 A类类型 也可以是 B类类型,没有A类或者没有B类,C类照样可以编译通过,正常运行,不像上面例子中的强耦合关系,必须是 某个类型, 其他类型皆不可的情形。我们可以得出结论:面向接口编程可以降低类之间的耦合性。在实际编程中我们应该尽量多使用面向接口编程来降低类与类之间的耦合性,增强代码的可扩展性。

类之间只能降低耦合性,无法消除耦合性!

“高内聚,低耦合”,用一句话概括就是写的代码尽可能专一的完成一个任务,且各段代码尽量模块化互相独立。

再举一个我们最常用的MVC三层架构关于类之间的耦合:
在这里插入图片描述
在service层我们需要使用dao层,通过在personServiceImpl类中创建了personDao接口的一个实现类对象,使得这两个类之间产生紧密的依赖关系,同样,如果没有personDaoImpl这个实现类,那么personServiceImpl这个类是无法通过编译的。在这里,我们创建对象的方式是直接new出一个我们需要的对象,这种方式将产生很强的耦合性,为什么这样说呢?
我们可以这样想,personDao是一个接口,会有很多的实现类,现在personServiceImpl类依赖的是它的其中某个实现类,那么下次我们如果要换成依赖另一个实现类呢?是不是就得重新new一个对象了,例如:personDao personDao=new personDaoImpl2();也可以说接口和实现类出现了强耦合。

spring为了降低这种耦合性,使用IOC容器来管理对象,当需要使用某个类,可以不再使用传统的new方式创建对象,而通过告诉spring容器,spring容器会在程序运行时查找你需要的类是否已在容器中,存在的话直接返回即可。
在这里插入图片描述
上面的例子就是spring的注解配置,我们要使用PersonDao接口的实现类,不直接通过new来创建,而是直接声明PersonDao类型变量,然后通过@Autowired注解配合@Qualifier注解从容器中拿到该具体的实现类对象,这样做的好处就是接口和实现类的耦合性不会很强,想要用接口的哪个实现类只需要修改@Qualifier注解的属性值即可。

补充一下自己的个人理解:个人认为通过new创建对象耦合度高的原因就是new出来的对象就被写死了,只能依赖那个对象,而使用Spring IOC容器或者面向接口编程却能不会被写死,想用哪个就直接去跟容器拿就好了。

什么是IOC?

IOC-Inversion of Control,即控制反转。它不是什么技术,而是一种设计思想。传统的创建对象的方法是直接通过 new 关键字,而 spring 则是通过 IOC 容器来创建对象,也就是说我们将创建对象的控制权交给了 IOC 容器。我们可以用一句话来概括 IOC:

   IOC 让程序员不在关注怎么去创建对象,而是关注对象创建之后的操作,把对象的创建、初始化、销毁等工作交给spring容器来做。

spring中,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

Spring IOC的底层是通过使用工厂模式+反射创建对象+配置文件实现的

猜你喜欢

转载自blog.csdn.net/can_chen/article/details/104939433