随笔 - 3  文章 - 0 评论 - 2 trackbacks - 0

类图是面向对象系统建模中最常见的图,类图显示了一组类、接口、协作以及它们之间的关系。类图用于对系统的静态设计视图建模。 在UML中类以矩形表示,具有名称、属性、操作、和关系等描述。接下来我们将全面的对类里面的每个元素的表现作出详细的介绍。
  • 类:
    • 在UML中类以一个矩形表示,类的名称用一个字符串表示。
    • 抽象类通过将类名改为斜体字表示。
    • 不能继承的类(叶子类,封闭类)通过在类名下面增加 leaf 特性说明。
  • 属性:
    • 属性在类下面的栏中列出,可以仅显示属性名。
    • 静态属性通过在属性名下加下划线表示。
    • 属性其他特征完整语法: [可见性] 属性名 [':'类型] [多重性] ['='初始值] [{特性串]}]
    • 不能重写属性通过在特性串中增加 leaf 特性说明。
  • 操作:
    • 属性在类下面的第二栏中列出,可以仅显示操作名。
    • 静态操作与静态属性同样通过在名称下加下划线表示。
    • 抽象操作与抽象类同样通过斜体字表示。
    • 操作特征完整语法: [可见性] 操作名 [([方向] 参数名 ':' 参数类型 ['=' 默认值])] [':' 返回类型] [{特征串}]
    • 不能重写的操作与属性一样使用特征串中增加 leaf 表示。
  • 可见性:
    • 可见性通过在属性或方法名称前增加特定的符号表示。公共的(+)私有的的(-)受保护的(#)包内的(~)
接下来我们一起来研究一下类之间的关系。
  • 依赖(dependency)是一种使用关系,他描述一个事物的规约变化可能影响到使用它的另一个事物。个人认为在参数或者方法体中使用到另外的类就是对该类有依赖的关系。use a
  • 泛化(dependency)用于描述子类到父类之间的关系。 Is a kind of
  • 关联(association)是一种结构关系,他描述一个对象与另一个对象相联系。 Has a
    • 双向关联(association)通过A对象可以找到B对象,B对象同样可以找到A对象的关联为双向关联。
    • 单向关联(direction-association)通过A对象可以找到B对象,但通过B对象不能找到A对象的关联为单向关联。
    • 聚合(aggreation)A对象是B对象的一个组成部份,但A对象同时可能是C对象的组成部分这种关联为聚合。
    • 组合(composition)A对象是B对象的一个组成部份,除非B对象将A对象转交给其他对象,否则A对象只能是B对象的组成部分,这种关联为组合。
posted @ 2010-04-10 20:36 FengLin 阅读(137) 评论(1) 编辑

我们从实际开发当地中找出一些例子,例如我接到一项任务,开发一个GPS数据解析器,用于根据GPS数据协议解析GPS发送回来的数据获得我们想要的数据

1.      一开始我接到任务,没有经过设计就开始编码了,首先新建GPSDataResolver类,添加Resolve方法,根据GPS传输回来的XML解析出经纬度字符串。OK,目前没有问题,程序稳定运行。

2.      过了一段时间,公司接到客户需求需要我们安装另外一家厂商的GPS,这时由于各个厂商的GPS数据解析协议都不同,因此我需要从新修改GPSDataResolver,为方法Resolve添加一个GPS类型参数,在方法内判断不同类型的GPS根据不同的协议解析。

3.      然后随着客户的增加,公司需要支持的GPS类型越来越多我就不断的修改GPSDataResolver,Resolve方法里的分支判断也越来越多,代码超过了300行,终于忍受不了将每一个GPS类型的数据解析都封装成一个方法,
终于Resolve方法解放了,代码行数减少到50行,但是每次有新的GPS类型加入,我还是在不断的修改GPSDataResolver类,即使方法的行数是减少到了50行,但是类的代码行数还是不断的在增加,显得类里面非常复杂,我同事说看到你这个类我都不想去维护了。

4.      受到同事的打击,我决心要寻找方法修改GPSDataResolver类,使他具有灵活性,扩展性和可维护性。于是我想到了工厂方法模式,将数据解析器抽象称为一个接口,根据这个接口,不同类型的GPS解析器可以具有不同的实现,客户端只需要依赖于IGPSDataResolver具体由哪个实现来解析数据完全由GPSDataResolverFactory控制。并且实现之间完全分离,就算由其他人来代替我继续开发新的GPS解析器也不用担心我原来的实现会影响到他,从而需要了解我之前的实现。

 5.      最后由于数据解析器代码结构、可扩展性、可维护性良好,合同伙伴公司也请求我们将数据解析器提供让他们使用,这时我想到了一点,为其他人提供服务应当尽量的简化,不要为他人增加复杂度,因此我将工厂合并到策略类当中,这样合作伙伴公司就连工厂类都不需要知道了。离,就算由其他人来代替我继续开发新的GPS解析器也不用担心我原来的实现会影响到他,从而需要了解我之前的实现。

 

 

说了这么多其实只是想表明软件开发编码不断改善的一个过程,就以上例子其实我们在一开始做开发的时候就应该想到哪一些会是相对稳定不会变化的部分(例如Resolve方法的参数)将其抽象出来以便以后对其进行扩展,也应该想到一些极为容易发生变化的地方(例如Rosolve方法根据不同GPS类型进行不同的解析)将其封装起来(封装到工厂里),只要我们遵循这样的设计思想,就可以为软件带来更多的可扩展性,可维护性。
 
 

对扩展开放,对修改封闭。开放封闭原则可以使软件系统面对需求的变动保持相对的稳定,但是无论模块是多么的封闭,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对哪种变化封闭做出选择,他必须先猜测出最有可能发生变化的种类,然后构造抽象来隔离哪些变化。
在我们最初编写代码是,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化。面对需求对程序的改动是通过增加新代码进行的,而不是更改现有的代码。我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。
开闭原则是面向对象涉及的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可扩展,可复用,灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而对于应用程序中的每个部分都可以地进行抽象同样不是一个好主意。拒绝不成熟的抽象与抽象本身同样重要。

 

 

posted @ 2010-03-11 21:41 FengLin 阅读(266) 评论(1) 编辑

在MasterPage中加入以下引用:

    <link href="JS/DivWindow/CSS/default.css"rel="stylesheet" type="text/css" />
    <link href="JS/DivWindow/CSS/alphacube.css" rel="stylesheet" type="text/css" />
    <link href="JS/DivWindow/CSS/spread.css" rel="stylesheet" type="text/css" />

运行页面,查看生成出来的HTML源码,发现奇怪的问题.标签变成这样了.

    <link href="JS/DivWindow/CSS/default.css"rel="stylesheet" type="text/css" />
    <link href="../JS/DivWindow/CSS/alphacube.css" rel="stylesheet" type="text/css" />
    <link href="../JS/DivWindow/CSS/spread.css" rel="stylesheet" type="text/css" />

 

原因是第一个标签 href="JS/DivWindow/CSS/default.css"rel="stylesheet" 少了空格.将空格去掉以后正常.

如果不放在MasterPage中则不会出现以上问题,很奇怪,不明白MasterPage的工作原理哈.

 

posted @ 2009-04-16 16:44 FengLin 阅读(55) 评论(0) 编辑
仅列出标题