思考:什么是耦合?什么是内聚?软件设计原则是什么?
耦合:衡量软件中各个层 / 各个模块的依赖关联程度。内聚:软件中各个功能模块内部的功能联系。软件设计原则:高内聚低耦合。
那我们该如何实现高内聚低耦合的软件设计原则?
高内聚(自己模块干自己的事)我们已经通过三层架构的方式进行解决了,那么接下来就是如何进行解耦合了。
要对代码进行解耦合首先得知道代码什么地方耦合了?
我们知道在三层架构中controller层要调用service层的服务,所以要在controller层声明service层的对象并进行初始化;同理service层要使用dao层的服务,所以要在service层声明dao层的对象并进行初始化。观察下图我们可以和清晰的观察到三层架构之间的耦合关系。
简单一点就是上层要调用下层的服务,所以要在自己的类里声明并创建下层的对象。
代码耦合可能会出现的问题。
以controller层为例,由于controller层要调用service层的服务 ,所以要在controller层声明service层的对象并进行初始化,那么一旦serviceImpl的代码有所改变,例如从Impl变为Impl2,那么不光要对service层代码进行改变,同样的还要对controller层进行改变(体现耦合性)。由此代码便很难以维护,因为各个模块之间的耦合性太高,牵一发而动全身。(我只改了service层的代码,但却还要改controller层的代码。)
人话:我只想聚焦我修改的那一个模块,不想改改这,改改那。
那该如何解决这个问题呢?换句话说,该如何解决模块之间的耦合关系呢?
spring给了我们解决方案:控制反转以及依赖注入
Q:什么是IOC以及DI?(重点)
控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为Bean。
这两种技术是如何解决模块之间的耦合问题的呢?
想理解这个问题我们还是得先聚焦到我们的问题本身。还是这张图,我们发现这两个模块之所以耦合的原因其实是因为我们要手动的去进行对象的创建,如果我们一旦对service层代码进行修改那么就会牵一发而动全身。思考一下如何解决这个问题呢?
那我们不手动进行创建对象,而是交给第三方管理,一旦我们再对service层代码进行修改,只需要告诉第三方管理我们想要使用哪个修改过的类就好了,(底层交由第三方去管理bean对象的创建)而不是手动的去更改对象创建实体,那么也就不用在修改service层代码之后,再去修改controller层的代码了,那不就解决这个问题了吗。
sping内部是如何实现对模块进行解耦合的?
上文的第三方管理其实就是我们鼎鼎大名的spring
为了实现上述功能,spring在内部其实会创建一个spring容器,spring会把你选定的bean对象都放在这个bean容器之中,有了这个bean容器,你就不再需要在手动的去进行类的实体化,这个工作将完全交由spring来完成。这就是spring的最核心的一大功能之一控制反转(IOC)(对象的创建控制权由程序自身转移到外部),并且一旦应用程序在运行时需要某个bean的实例化,spring就会自动的为那个类进行实例化,这同样也是spring的最核心的功能之一依赖注入(DI)(容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。)
小结:
1. 实现分层解耦的思路是什么 ?• 将项目中的类交给 IOC 容器管理( IOC ,控制反转)• 应用程序运行时需要什么对象,直接依赖容器为其提供( DI ,依赖注入)