模式应用(一) 软件架构
关于这篇文章我一直想写,但每次总是没有一个闲下来的时间,现在试着挤每天的闲暇时间一点点完成。
一直以来我都想做一个软件架构师,所以我在平时的开发中除了保证写出高质量的代码外,还会从架构者的角度来仔细推敲整个应用。当然了这个架构主要是指的代码的架构,那么推敲的依据主要来自三个地方:
1.GRASP
每当遇到软件分层,类似于业务逻辑放在那个类哪个层等问题时,我通常都会参考GRASP,General Responsibility Assignment Software Pattern。包括以下几个原则:
A.Information Expert 信息专家
B.Creator 创建者
C.Low Coupling 低耦合
D.High Cohesion 高内聚
E.Controller 控制器
F.Polymorphism 多态
G.Pure Fabrication 纯虚构
H.Indirection 间接:避免对象间直接耦合,合理分配职责
G.Protected Variations 受保护变化:开闭原则。
虽说每个思想懂,但真正能用在实际开发中还是有一定难度的,具体的介绍可以参考大师CRAIG LARMAN的《UML与模式应用》。
2.Design Patterns
古人练剑分三层境界。第一层是每个招式都熟记于心, 没事就拿出来练练,比武时按照自己的套路出剑,第二层就是没有招式,只有思想,假如想解掉别人的剑,那目标就是解剑,随便出剑都可以做到。第三层就是人剑合一,这种境界就已经不依赖与剑了,身边的任何物体包括自己都可以是一把剑,都可以置对方于死地。
世间万物皆相通,我认为模式的学习也是有三种阶段,23种模式熟记于心,遇到具体项目套相对应的设计模式,虽然有点死板,但给软件的维护和扩展带来很大好处,这是学习设计模式的第一层。第二层就是大脑中已经没有具体的模式,只知道如果要解耦,那么就这样做,如果追求运行速度,就那样做,这就不一定是23种模式的一种了。如果已经有前两层的功力,那就要追求人设计模式合一,这时就有很多变化,创造模式,不会依赖与语言(C, C++, JAVA等等),各个领域的设计模式等等。估计Erich Gamma应该到了第三层境界了吧。
3. 我的前辈
他们在这方面很有经验,架构这个东西就是平时要积累丰富项目经验,看看国外的一个个大牛,都不是40多岁的人,所以我就很讨厌某些言论说软件是吃青春饭的…
在正常的情况,在我看来,现在的软件设计从大的角度来讲就是复用(Reuse),从小的角度来讲就是解耦(Decouple或者separate concern)。作为一名优秀的程序员,开发一个App,写一句代码都要考虑到你写的这个类与其它类的关系,是不是多余的依赖,适不适合扩展等等。由于这段时间工作的需要,我接连转了三个项目,目睹了每个项目架构的优缺点,加之前不久我又进行了IJC关于RUP的培训,与IJC的David和蒋胜老师深入的讨论了软件开发过程,所以我想把学到的一些设计方法举个例子来说明。
在进入主题之前我想先叙述一些概念。
概念1:由面向过程到面向对象绝对是一个质的飞跃,我认为OO最大的优点在于它的程序设计和现实世界是相对应的,从23种设计模式的名字上面也有体现。工厂,代理,适配器等等。
概念2:MVC(Model-View-Controller,模型—视图—控制器模式)用于表示一种软件架构模式。它把软件系统分为三个基本部分:模型(英语:Model),视图(View)和控制(Controller)。视图(View)代表用户交互界面,控制(Controller)可以理解将模型与视图匹配在一起,共同完成用户的请求。模型主要是指业务流程的具体细节,整个过程如图1。那么其实在实际的开发中MVC还是有很多局限性的,后面会通过一个例子给出一个我的改进版。
图1
概念3:RUP
RUP(Rational Unified Process,统一软件开发过程,统一软件过程)是一个面向对象且基于网络的程序开发方法论。根据Rational(Rational Rose和统一建模语言的开发者)的说法,好像一个在线的指导者,它可以为所有方面和层次的程序开发提供指导方针,模版以及事例支持。 RUP和类似的产品--例如面向对象的软件过程(OOSP),以及OPEN Process都是理解性的软件工程工具--把开发中面向过程的方面(例如定义的阶段,技术和实践)和其他开发的组件(例如文档,模型,手册以及代码等等)整合在一个统一的框架内。
抓其精髓就是使整个开发过程统一,可管理。用例驱动,以架构为中心,增量与迭代,是RUP的主要思想。RUP是一个很复杂的过程,但好在它在每个项目中使用时可以因地制宜,有效的裁减可以使RUP在工程中发挥最大的威力。作为一个程序员,我首先要关心的是有关代码架构的问题,RUP有一个核心的思想Separate concern,也就是分离关注点。这也刚好体现了面向对象的一个思想:解耦。那么RUP中最能体现它Separate concern的应该就算它的Minimal和Extension了,当然还有一些其它的体现方式,我会在下篇实例中详细介绍。
简单来说Minimal指的是那些上不依赖于表现层,下不依赖于数据库,操作系统等,可以在任何环境下运行的纯业务逻辑程序,最主要的还是Minimal部分的代码可以复用。Extension包括Minimal,它依赖于某个特定的底层程序或者操作系统。Minimal和Extension类似于图2的关系。
图2