Dive into Spring framework -- 了解基本原理(一)

在继续咱们的分析以前,推荐各位静心来读一下<<Expert_OneOne_J2EE_Design_and_Development>> 第四章, 正如spring BeanFactoryjava

API 中描述的。这一章主要说明了设计原则,设计模式,异常处理,反射等各个方面。原本也是想着直接来分析代码,但咱们应该知其然也要知其因此然,为了能加深理解Johnson建立框架的设计思路,就引入了这一部分。web

从spring的核心概念IoC入手,IoC的主要含义究竟是针对哪一个部分来讲明的?是在xml配置的对象之间的关系么?针对这个IoC,咱们应该如何应用?仍是应该看看spring究竟是怎么应用的。spring

关于设计原则,比较推荐看看《敏捷软件开发》,这里面有最基本的设计原则的汇总,而expert书中都有不谋而合的理论。为了全面,仍是结合了《敏捷》里面的原则,主要罗列以下:设计模式

OCP(开闭原则)架构

在平常的开发分析过程当中,常常会遇到设计问题,咱们的框架须要知足任何需求的变动,设计模式里面常常这样来讲明某个设计模式如何应对变化。可是全部的设计模式实际上都是建议咱们如何应对这样的变化,应该如何考虑咱们的框架,因而按照《敏捷》里面的定义:对扩展开放,对更改封闭。因此对于特定的需求设计,主要须要考虑的就变成了,如何来划分扩展的部分和更改的部分。再也不重复《敏捷》里面的例子,可是看完其Shape的例子,首先应该考虑的就是抽象,抽象就是咱们要找的扩展和更改的界限。框架

在接收到一个需求的时候,咱们能够不顾一切的面向对象,直接写出一些class,而后让他们互相依赖,快速的完成这些功能。那么接下来若是还有任何需求变动,就要直接修改那些类之间的依赖关系,这就如一个食物链,若是最底层的生物有什么问题,那这条链子就会受影响,固然食物链这个类比有点牵强,毕竟一种生物不会一直吃一种食物,但咱们假设是那样的。类之间的直接依赖相似于这样的关系,若是咱们变了最底层的依赖,可能影响它的上层,上层也有可能进一步影响上层。若是像食物链那样,每种生物有多种食物,也就是在处理依赖时,能给依赖多重选择。应该如何来考虑这个“多重选择” , 固然应该是接口。《敏捷》在Shape示例中,由过程性代码转变成OO代码,主要是加入了抽象,使得“引用”依赖接口中的“动做”,而并非“具体对象”。这是须要特别强调的,就是不要依赖对象,要依赖动做,而java里面的interface就是“动做”的集合。spa


SRP(单一职责)设计

首先咱们要明确的是何为职责,根据《敏捷》里面的定义,“引发变化的缘由”。在平常开发里面,这种情况太广泛了,做为开发大军中的一员,就是这么过来的,曾经有个action类能够有3W行代码。想一想这个代码行数,就知道致使它发生变化的缘由多的很。若是(要是都有若是就行了)当年咱能顿悟出这么几个原则,就不说当年了,如今起就应该结合SRP和OCP来进行最初始的设计划分。orm

通常的web应用项目,在action以后老是按照三层的概念实现底层,一个使用struts 1/struts2的项目老是会有比较雍容的action层,但service层却仅仅是dao的封装。因而一个贫血的架构就变得家喻户晓。xml

但咱们常常忽略那些业务上的划分,那么结合框架和业务,应该如何来考虑这种划分呢?首先一个action受http的影响(输入和输出),输入参数的各类验证,而后根据各类判断来调用某个service。从总体架构上讲,虽然是隔离了dao,但在业务层(action+service)会很臃肿。尤为是action就是个定时炸弹,承担各类职责。这个时候,就应该考虑一下设计模式来隔离一部分,划分出变化的和不变的。


LSP(Liskov替换原则)

《敏捷》定义为:子类型必须可以替换基类型。

这个定义里面有着对继承关系的强制性定义。其实在咱们的平常使用中,出现比较多的问题应该是,一个类继承了不少没用的功能,这可能是因为没有明确划分功能范围引发的接口方法污染。其实在一个子类不能彻底替换父类的时候,就应该引发咱们的警觉,是否应该按照SRP和OCP进行调整,LSP就像是一个标杆原则,老是要咱们检验继承关系。


DIP(依赖注入)

《敏捷》认为全部的依赖都不该该是直接的类依赖,而应该是基于抽象。这个跟《Expert》的Achieve Loose Couple with Interfaces的出发点是一致的。上层不该该直接依赖底层,而都应依赖抽象,这里要强调两个东西,一个是何为抽象,一个是何为依赖。抽象应该是动做的抽象,那就是接口。而依赖则不只仅是引用某个对象算是依赖,实现了某个接口也是一种依赖。


ISP(接口隔离)

在SRP的阐述中,就提及那个场景,咱们的一个类里面可能不得不实现没必要要的接口,这些上层接口的变化会影响实现类。在ISP中,就要求“不要强迫用户依赖不使用的方法”。接口的划分应该是基于业务须要的,若是一个interface中包含了几个业务动做,那么这不只仅不符合SRP的原则,同时给依赖方也带来没必要要的麻烦,那就是他们不得不实现不用的方法。出现这种状况的时候,咱们应该考虑精细划分客户方的范围,从而针对不一样的客户方,提供特别的接口动做。


以上主要是从《敏捷》中借鉴来的基本的设计原则,最开始的时候说过了,就是由于有殊途同归的基础,才考虑到直接引用《敏捷》的内容。在我看完《敏捷》以后的感受就是,这本书要一直伴随个人左右,要深刻的实践体会那些设计原则和模式。实际上这些原则都不能独立的套用,而是相辅相成的。在上面的原则描述中,都基于一个最基本的基础就是抽象。依赖抽象去实现OCP,如确认一种依赖以后,为了之后的变化,上层依赖的是接口,而底层则多是经过策略模式等设计模式来开放给需求的变动,而这又偏偏是DIP所要求的。spring做为使用如此普遍的框架,其设计必然符合这些基本原则,才能为咱们提供那些不变的依赖,和咱们业务中变化的需求,那么spring中的OO设计原则又特别强调哪几个方面?


再次强调,《Expert》的chapter 4绝对值得读5遍以上,这一章摊开来就能够写一本书,其中有一些引用资料,也极有参考价值。在写这篇blog的时候,最开始特别想赶进度快点写点东西,可是再来回味《Expert》却发现之前那么一些原则,在前几年的开发里面好像没有多少顾忌的。因此就把这一章反复读了4遍,才略下本文,但愿之后可以铭记和实践。


下一部分看看spring的做者Rod Johnson是参考了哪些基本原则,考虑到哪些方面来实现了伟大的spring framework?

转载请注明出处。 

相关文章
相关标签/搜索