UML类图与面向对象设计原则
1. 引言
从大一开始学习编程,到如今也已经有两年了。从最初学习的Html,Js,JaveSe,再到JavaEE,Android,自己也能写一些玩具。学习过程中也无意识的了解了一些所谓的设计模式,如今打算系统的学习。学习以书《设计模式的艺术——软件开发人员内功修炼之道/刘伟著》为主。
所谓设计模式,即是前人对某类相似问题的抽象给出的解决方案。书中给出了23(Gof)+1(简单工厂模式)种设计模式。每种模式的学习将关注以下几点:名称(Name),问题(Problem),解决方案(Solution),效果(Consequence)。
2. UML
先从UML学起。
从它的全称Unified Modeling Language就可以看出,它是一种分析设计语言(建模语言)。
主要有视图(View),图(Diagram),模型元素(Model Element),通讯机制(General Mechanism)几个部分。
类的属性和方法表示方式分别如下:
可见性 属性名:类型 [ = 默认值]
可见性 方法名(参数列表) [ :返回值类型]
例子如下:
① 关联关系
1)双向关联。例子如下:
2)单向关联。例子如下:
3)自关联。例子如下:
4)多重性关联。例子如下:
5) 聚合关系。例子如下:
6)组合关系。与聚合关系类似,不同之处在于,组合关系更强调一种依附(寄生)关系。例子如下:
② 依赖关系。例子如下:
View(视图)类的draw方法依赖于Canvas(画布)类的传入。
③ 泛化关系(继承关系)。例子如下:
④ 接口与实现关系。例子如下:
3. 面向对象设计原则
① 单一职责原则
一个类只负责一个功能领域中的相应职责。或者说,就一个类而言,应该只有一个引起它变化的原因。
单一职责原则的目的是实现高内聚、低耦合,其核心思想是一个类不能太“累”。在软件系统中,一个类的职责越多,它被复用的机会便越小。
如下面这个例子: CustomDataChart类承担了太多的责任:既要负责连接数据库,又负责获取查询客户,还有显示图表的方法。合理的做法是分为3个类:
1)DBUtil:包含连接数据库方法getConnection();
2)CustomDao:包含查找Customs方法findCustoms()方法;
3)CustomDataChart:包含显示图表的方法displayChart();
重构后的结构图如下:
重构的好处是显而易见的:我们将不同职责的方法划分在不同的类中,便于阅读理解;当某个职责发生变化时,如更换了数据库,我们只需要修改DBUtil中的getConnection()方法,而其他的代码都不变。
② 开闭原则
一个软件实体应当对扩展开放,对修改关闭。即软件实体应做到在不修改原有代码的情况下进行扩展。
任何软件都面临一个很重要的问题,即需求会随着时间的变化而变化。但面临新的需求时,软件应尽量保证原有系统的稳定,在不修改原有系统代码的情况加入新的扩展模块。
③ 里氏代换原则
它的严格定义如下:
一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换为o2时,程序P的行为没有变化,那么类型S是类型T的子类型。
它的通俗版定义是:
所有应用基类(父类)的地方必须能被替换为其子类。
即我们在编程时,应面向接口编程。
④ 依赖倒转原则
抽象不应依赖于细节,细节应当依赖于抽象。换言之,应面向接口编程,而不是针对实现编程。
当我们在面向抽象层编程时,要将具体类的对象通过依赖注入的方式注入。常用的注入方式有:构造注入、设值注入和接口注入。
⑤ 接口隔离原则
要尽量使用多个专门的接口,而不要使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
⑥ 合成复用原则
要尽量使用对象的组合,而不是继承来达到复用的目的。
⑦ 迪米特法则
一个软件实体应尽量少的与其他软件实体发生关系。