迷途书童

敏感、勤学、多思
随笔 - 77, 文章 - 4, 评论 - 86, 引用 - 0
数据加载中……

面向对象的设计

 

    最近看完了《设计模式精解》这本书,感觉收获颇丰,为了不让时间带走我的收获,在此将我的一些感想和收获记录下来,以飨大众。

    首先回顾一下历史,看看能不能激起某些同志的共鸣,耐心的看完下面的部分,多给我提提意见指指路 ^_^

    从大学三年级开始到将近工作一年的这段时间里,我的角色是一个代码编写者,这段时间的主要心理状态是一看到功能描述就会去想实现。大三下学期的时候写过一个 asp 的内容管理系统,那个时候完全没有代码复用,设计系统结构的概念,完全是见招拆招,有几个很壮观的页面的代码超过了 25k ,每当我看到这几个页面时我就很自豪(我终于可以写出 25k 的代码了),但是我从来没有维护过它们,不是没有 bug ,是看起来很头疼!毕业后的头半年写过一个 jsp 的内容管理系统,这是我头一次接触面向对象的语言,不过设计、实现的时候还是有很多在学校时做的 asp 系统的影子,几乎就是把 jsp asp 用,不过就在这段时间里开始了解了 struts ,知道它是一个 mvc 框架,仅此而已,又看完了 java 编程思想,多多少少有了点对象的概念,知道多态继承封装是怎么回事,但是却不知道什么时候去使用它们。直到后来要做一个类似 web 容器的东东,看完了一个高手设计的开源框架的代码,又囫囵吞枣的读完了设计模式,于是开始对面向对象有感觉了,知道要针对接口编程,某些特定场景下要用某些设计模式。但是我仍然清楚的认识自己还停留在实现层次,如果给我一个系统让我设计,我理不出合理的软件架构,不知道怎么去设计可扩展的,结构清晰的,易使用的软件架构。我努力的想跳出那个圈,但是我找不到向上的阶梯 ……

    接下来的日子里,我做一些平台的维护工作,因为平台是各种模块的集合,如果用户使用平台出了问题,有可能是各种各样的模块的问题,这段时间里,我得以接触多个模块,学会了怎样快速理清软件系统的层次。后来,我承担了一些平台的需求分析,开始自己去思考怎么样设计软件的层次,由于缺乏经验,感觉这些工作都做得不好。但是这一切,都是我不可或缺的积累,我依稀能看到那个向上的阶梯 ……

    直到后来,我遇到了它(广告开始):《设计模式精解》。此书以一个实际的例子阐述了软件设计的过程,清晰的描述了系统设计应遵循的规则,让我真正理解了创建型模式,结构型模式,行为型模式的涵义。从此以后,让我 …… ,实在是程序员,架构师等人之必备良书。等等,鸡蛋和西红柿都捐给希望工程吧,不要浪费 ^_^ 。(题外话:光有理论不实践不能深刻的理解理论,如果在理论的指导下实践会取得事半功倍的效果,如果我没有需求分析的经验,当我看这本书时不会有那么深的体会。我们在努力工作的同时,还是要多看看书拔高自己。)

 

 

 

    首先阐述一下面向对象的一些基本概念。

什么是对象?就像《 java 编程思想》里说的那样,是属性与行为的集合吗?这只是实现层次的理解,从概念层次上讲,好的对象是一个能承担责任的载体,它对自己负责,能独立完成自己的工作。(像极了我们优秀的同事 ^_^ );从规格层次上讲,对象是一系列可以被其他对象或自己调用的方法。

什么是多态?多态就是同一种事物表现出的多种形态,比如白马,黑马,灰马等等都是马,但是都是不同的马。映射到面向对象系统中就是一个抽象类的多种实现。

什么是继承?让一个类成为另一个类的特殊类型。这些特殊类型的类被称为父类的子类。

什么是封装?封装意味着任何形式的隐藏―― > 数据隐藏,类隐藏,实现隐藏。数据隐藏就是隐藏对象的内部属性;类隐藏就是隐藏具体类,将抽象类或接口暴露给客户;实现隐藏就是隐藏内部的实现,提供供用户调用的接口。

为什么要面向接口编程?接口能够有效对类功能进行分组,避免客户了解和他不相关的知识,另外,接口是需求中比较稳定的部分,而实现是和具体环境相关联的。

下面就以一个简单的例子《图形显示系统的设计》来说明一个软件设计的过程。

功能描述

要设计一个图形显示系统,该系统要支持在屏幕上或在文件中打印出四种图形:圆形,方形,三角形,五角形。

1.   建立分析 matrix

  

功能

显示在屏幕中

显示在文件中

取得图形位置信息

取得图形在屏幕中的位置信息

取得图形在文件中的位置信息

显示图形

根据位置信息在屏幕中打印图形(圆形,方形,三角形,五角形等)

根据位置信息在文件中打印圆形(圆形,方形,三角形,五角形等)

 

2.   根据场景确定系统使用哪种设计模式

在系统设计时,我们应遵循“先确定规格,后确定实现”的原则,因为规格表示系统的共同部分,而实现表示系统的特定部分。

我们先观察上面的矩阵的第一列。

看完第一列,我们发现,图形显示系统要完成图形的显示必须做两件事,第一件事是是取得图形的位置信息,第二件事是显示图形。

于是一个表示系统规格的基类就出来了。

DisplaySystem

 

 

+ getLocation();

+ display();

 

 

再看矩阵的第二行,我们发现,如果图形显示的场所(文件 / 屏幕)不一样,那么位置的计算策略也不一样。我马上想到了策略模式,那么怎样让策略脱离系统独立演化呢?用组合。

再看矩阵的第三行,我们发现,图形不一样,显示的逻辑也不一样。还有一个变化点就是,在文件中画出点的逻辑跟在屏幕中画出点的逻辑不一样。这个功能模块中存在两个变化点,为了可扩展性考虑,我们必须要让这两个点能独立演化。于是我想到了桥梁模式。

根据以上的分析,我们得到系统的细粒度的设计如下:

DisplaySystem

FileLocation

+ getLocation()

ConsoleLocation

+ getLocation()

Location

Display

……

……

CircleDisplay

SquareDisplay

DrawDot

FileDraw

ConsoleDraw

由于缺乏专业建模工具,设计图暂且画成这样。

到此为止,我们看看现有的系统。该系统已经满足了现有的需求。如果以后新增了一个需求,要支持画六边形,那么我只要再创建一个继承于 Display HexagonDisplay 。如果又增加了一个需求,要支持在远程屏幕上画图形,那么我们只需要再增加一个继承于 DrawDot RemoteConsoleDraw 类。

那么到此结束了么?我们再仔细看看设计图。图中有三个继承体系: Location Display DrawDot ,我们是不是又看到了抽象工厂模式的用武之地?关于怎样在此系统中加入抽象工厂模式就不再说明了。

 

回顾一下该系统设计中用到的模式:

设计模式类型

设计模式

创建型模式

抽象工厂模式

结构型模式

桥梁模式

行为型模式

策略模式

对三种类型的设计模式的介绍:

设计模式类型

说明

创建型模式

解决类或对象之间如何交互和如何分配职责的问题

结构型模式

解决如何正确的组合类或对象的问题

行为型模式

解决类或对象之间如何交互和如何分配职责的问题

结合这个例子,再看看这些概念,是不是理解更清晰了?

 

关于系统设计的一些注意事项:

1.   不要打算去设计一个完美的系统,我们永远无法预测用户会有什么样的需求。

2.   设计系统的时候要特别注意系统中的变化点,将无法预知的变化点提取出来让其独立演化。

3.   牢记“先确定规格,后确定实现”的原则。要不然我们会一头扎进无穷尽的变化的汪洋大海。

4.   根据场景定模式。每一种模式都有特定的适应场景。

5.   不要滥用设计模式。

 

 

 

    曾几何时,苦于做面向对象系统设计不得其门而入(苦于怎样确定系统内的实体),于是苦寻系统设计法则,曾经见过这样一句名言:“根据名词确定类,动词确定行为”。当时觉得如获至宝,茅塞顿开。现在看来,这么做固然能设计出一个系统,但不一定能设计出一个高扩展性的系统。要设计出一个高扩展性的系统,必须让系统能够包容变化,变化也可以成为系统中的一个类(为了让变化独立演变),所以,我认为那句良言仅供参考。

    另外,我觉得《设计模式精解》书中所说的“根据场景选用模式”非常经典,如果我们能在平时工作中多多留心,积累一些“特定场景下使用特定模式”的案例,再拿出来共享一下,我相信,我们人人都能成为优秀的设计师。


文件: 面向对象的设计.rar
大小: 12KB
下载: 下载

posted on 2006-05-05 00:17 迷途书童 阅读(1457) 评论(4)  编辑  收藏 所属分类: 系统设计

评论

# re: 面向对象的设计  回复  更多评论   

Useful expierence,thanks for sharing ^_^
2006-05-05 05:48 | 鸟不生蛋蛋的地方

# re: 面向对象的设计  回复  更多评论   

设计师要做的主要是从众多的解决方案中选择合适的方案,在这样的背景下很多时候不是设计模式能解决的,而是需要积累足够的经验。
2006-05-05 22:10 | BlueDavy

# re: 面向对象的设计  回复  更多评论   

我认为方案跟设计是两个层面的东西,可以分别来谈。
2006-05-06 15:39 | landy

# re: 面向对象的设计  回复  更多评论   

这本书我也看了,共同努力。希望你的文章能持续发布。
2006-05-08 08:58 | Qutr

只有注册用户登录后才能发表评论。


网站导航: