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

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

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

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

OCP(开闭原则)

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

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

SRP(单一职责)

首先我们要明确的是何为职责,根据《敏捷》里面的定义,“引起变化的原因”。在日常开发里面,这种状况太普遍了,作为开发大军中的一员,就是这么过来的,曾经有个action类可以有3W行代码。想想这个代码行数,就知道导致它发生变化的原因多的很。如果(要是都有如果就好了)当年咱能顿悟出这么几个原则,就不说当年了,现在起就应该结合SRP和OCP来进行最初始的设计划分。

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

但我们经常忽略那些业务上的划分,那么结合框架和业务,应该如何来考虑这种划分呢?首先一个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?

转载请注明出处。

Dive into Spring framework -- 了解基本原理(一)的更多相关文章

  1. Dive into Spring framework -- 了解基本原理(二)--设计模式-part2

    Template模式 Template模式顾名思义是提供了一种模板,也就是针对某种业务提供了模范框架.这个在spring中是属于核心模式的,因为其ApplicationContext抽象类就是模板模式 ...

  2. Dive into Spring framework -- 了解基本原理(二)--设计模式-part1

    比较巧,自己在接触设计模式的时候,也刚开始学习spring,但可惜的是,真的仅仅在学习“用”spring,每天都沉浸在会痛快的完成spring各种配置的快乐之中,但对成长无用.其实当初就清楚,spri ...

  3. Dive into Spring framework -- 搭建spring 源码的开发环境

    spring是一个类之间依赖的管理容器,大家都知道,但我们中很多人都仅仅停留在使用的层面,但spring本身具有极大的研究价值,所以在使用了几年spring之后,还是想深入的探究一下其根源.记录于此, ...

  4. 一步步从Spring Framework装配掌握SpringBoot自动装配

    目录 Spring Framework模式注解 Spring Framework@Enable模块装配 Spring Framework条件装配 SpringBoot 自动装配 本章总结 Spring ...

  5. Spring Boot之从Spring Framework装配掌握SpringBoot自动装配

    Spring Framework模式注解 模式注解是一种用于声明在应用中扮演“组件”角色的注解.如 Spring Framework 中的 @Repository 标注在任何类上 ,用于扮演仓储角色的 ...

  6. 浅谈对Spring Framework的认识

    Spring Framework,作为一个应用框架,官方的介绍如下: The Spring Framework provides a comprehensive programming and con ...

  7. Hello Spring Framework——依赖注入(DI)与控制翻转(IoC)

    又到年关了,还有几天就是春节.趁最后还有些时间,复习一下Spring的官方文档. 写在前面的话: Spring是我首次开始尝试通过官方文档来学习的框架(以前学习Struts和Hibernate都大多是 ...

  8. 手动创建Spring项目 Spring framework

    之前学习框架一直是看的视频教程,并且在都配套有项目源码,跟着视频敲代码总是很简单,现在想深入了解,自己从官网下载文件手动搭建,就遇到了很多问题记载如下. 首先熟悉一下spring的官方网站:http: ...

  9. 转-Spring Framework中的AOP之around通知

    Spring Framework中的AOP之around通知 http://blog.csdn.net/xiaoliang_xie/article/details/7049183 标签: spring ...

随机推荐

  1. nginx的相关信息

    Nginx安装 nginx官网:https://nginx.org/ 安装准备:nginx依赖pcre库,要先安装pcre(nginx在rewrite时需要解析正则,PCRE是正则解析库) yum i ...

  2. (转)Spring整合Jpa

    Spring-data-jpa 学习笔记(一) 作者:zeng1994  出处:http://www.cnblogs.com/zeng1994/ Spring家族越来越强大,作为一名javaWeb开发 ...

  3. MySQL 参数

    I see a lot of people filtering replication with binlog-do-db, binlog-ignore-db, replicate-do-db, an ...

  4. oracle dataguard参数

    在整个dg配置中,最复杂的也许就是参数的配置了,并且有许多参数都可以延伸出去讲很多,所以今天我们来看看dg的参数配置,顺便加上一点dataguard进程相关的信息,帮助理解. 在配置dg的过程中,我们 ...

  5. socketserver 并发连接

    socketserver.TCPServer Example server side 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  6. crm 使用stark组件

    # Create your models here. from django.db import models class Department(models.Model): "" ...

  7. Creating an generated Earth AVI with C++

    Creating an generated Earth AVI with C++        EarthGenerator.cpp /*    EarthGenerator.cpp An examp ...

  8. The Cheap KD 10 design is not too far of a departure

    Kevin Durant's Cheap KD 10 have to do with to determine the greatest spotlight they have seen around ...

  9. __all__方法的作用

    在__all__里面写了谁,到时候就只能用谁,其他的用不了,from 模块 import *时就只能用__all__里的 __all__=['test1','Test'] def test1(): p ...

  10. 【转】阿里巴巴技术专家杨晓明:基于Hadoop技术进行地理空间分析

    转自:http://www.csdn.net/article/2015-01-23/2823687-geographic-space-base-Hadoop [编者按]交通领域正产生着海量的车辆位置点 ...