面向对象分析与设计-概念

“Success isn’t about how your life looks to others. It’s about how it feels to you.”

面向对象分析与设计全书分为理论和应用两部分,深刻剖析了面向对象分析与设计的概念和方法。

复杂性

软件的复杂性是一个基本特征,而不是偶然如此。——Brooks

如上所述,软件的复杂性是其固有的属性。这种固有的复杂性有4个原因:

  • 问题域的复杂性
  • 管理开发过程的困难性
  • 软件中随处可能出现的灵活性
  • 刻画离散系统行为的问题

正因为这种复杂性的本质,所有复杂系统都存在5个共同的属性:

  • 层次结构

复杂性常常以层次结构的形式存在。复杂的系统由一些相关的子系统组成。这些子系统又有自己的系统,如此下去,直到达到某种最低层次的基本组件。

  • 相对本原
  • 分离关注
  • 共同模式
  • 稳定的中间形式

软件开发面临的困境是:要开发的软件系统的复杂性在增加,而我们处理复杂性的能力却有局限。怎样才能解决这个困境?

  • 分解
  • 抽象
  • 层次结构

对象模型

对象模型主要是为了解决大规模编程的遇到的问题。使用对象模型能够帮助我们探索基于对象和面向对象编程语言的表达能力。利用对象模式不仅鼓励软件的复用,而且鼓励整个设计的复用,这导致了可复用应用框架的产生。使用对象模型将得到构建在稳定的中间状态之上的系统,这样的系统更适合变化。

OOP、OOD、OOA

究竟什么是面向对象编程(OOP)?

面向对象编程是一种实现的方法,在这种方法中,程序被组织成许多组相互协作的对象,每个对象代表某个类的一个实例,而类则属于一个通过继承关系形成的层次结构。

该定义的要点在于三点,一个程序如果不满足这三点,就不是面向对象编程:

  • 利用对象作为基本逻辑构建块
  • 每个对象都是某个类的一个实例
  • 类与类之间可以通过继承关系联系在一起

究竟什么是面向对象设计(OOD)?

面向对象设计是一种设计方法,包括面向对象分解的过程和一种表示法,这种表示法用于展示被设计系统的逻辑模型和物理模型、静态模型和动态模型。

对面向对象分解的支持是面向对象设计与结构化设计的不同之处:前者利用类和对象抽象来构建逻辑系统结构,后者则利用算法抽象。

究竟什么是面向对象分析(OOA)?

面向对象分析是一种分析方法,这种方法利用从问题域的词汇表中找到的类和对象来分析需求。

面向对象分析的重点在于构建真实世界的模型,利用面向对象的观点来看世界。

OOA、OOD、OOP三者关系如何?

面向对象分析的结构可以作为开始面向对象设计的模型,面对对象设计的结果可以作为蓝图,利用面向对象编程方法最终实现一个系统。

对象模型要素

每一种编程风格都是基于它自己的概念框架。对于所有面向对象的东西,概念框架就是对象模型。这个模型有四个主要要素:

  • 抽象

抽象描述了一个对象的基本特征,可以将这个对象与所有其他类型的对象区分开来,因此提供了清晰定义的概念边界,它与观察者的视角有关。

对于给定的问题域决定一组正确的抽象,就是面向对象设计的核心问题。

  • 封装

封装是一个过程,它分隔构成抽象的结构和行为的元素。封装的作用是分离抽象的概念结构及其实现。

抽象关注对象的可以观察到的行为,而封装关注这种行为的实现。

  • 模块化

模块化是一个系统的属性,这个系统被分解为一组高内聚(将逻辑上相关的抽象放在一起)、低耦合(减少模块间的依赖关系)的模块。

抽象、封装、模块化的原则是相辅相成的。一个对象围绕单一的抽象提供一个明确的边界,封装和模块化都围绕这个抽象提供了屏障。

  • 层次结构

层次结构是抽象的一种分级或排序。在复杂系统中,最重要的层次结果是它的类结构(“是一种”层次结构——继承/派生)和对象结构(“组成部分”层次结构——聚合/组合)。

所谓“主要”,指的是如果一个模型不具备这些元素之一,就不是面向对象的。

对象模型有三个次要要素:

  • 类型

类型是关于一个对象的类的强制规定,这样一来,不同类型的对象不能够互换使用,或者至少它们的互换使用受到非常严格的限制。

  • 并发

并发时一种属性,它区分主动对象和非主动对象。主动对象可以代表一个独立的控制线程。我们可以将世界概念化为一组协作的对象,其中某些是主动的,因此作为独立活动的中心。

  • 持久

持久是对象的一种属性,利用这种属性,对象跨越时间(例如,当对象的创建不存在了的时候,对象仍然存在)和空间(例如,对象的位置从它被创建的地址空间移开)而存在。

所谓“次要”,指的是这些要素是对象模型的有用组成部分,但不是本质的。

类与对象

对象

对象的定义:

一个对象是一个具有状态、行为和标识符的实体。结构和行为类似的对象定义在他们共同的类中。“实例”和“对象”这两个术语可以互换使用。

对象的状态:

对象的状态包括这个对象的所有属性(通常是静态的)以及每个属性当前的值(通常是动态的)。

一个属性是一种内在或独特的特征、特点、品质或特性,使一个对象区别于别的对象。

对象的行为:

行为是对象在状态改变和消息传递方面的动作和反应的方式。对象的行为代表了它外部可见的活动。

对象的状态影响对象行为的结果,对象的行为改变了对象的状态,一个对象的状态代表了它的行为的积累效果。

一个对象的行为包含了其操作的综合。常见的操作如下:

  • 修改操作
  • 选择操作
  • 遍历操作
  • 构造操作
  • 析构操作

对象的标识符:

标识符是一个对象的属性,它区分这个对象与其他所有对象。

对象之间的关系

链接代表了具体的关联,通过这种关联,一个对象(客户)请求另一个对象(服务提供者)的服务,或者通过这种关联从一个对象导航到另一个对象。

聚合表明一种整体/部分层次关系,提供了从整体导航到它的部分的能力。

类的本质

类的定义:

类是一组对象,它们拥有共同的结构、共同的行为和共同的语义。一个对象就是类的一个实例。类起到的作用是在一种抽象和所有它的客户之间建立起协议。通过在类的接口中记录下这些决定,一种强类型的编程语言可以在编译时检查是否违反了这一协议。

类之间的关系:

类之间存在三种基本关系:一般/特殊关系(是“一种”关系,玫瑰是一种花)、整体/部分关系(是”组成部分“关系,花瓣是花的部分)、关联(语义上的依赖关系,瓢虫和花之间的关系)。

  • 继承:一个类实现一个接口或一个类泛化另一个类。是一种is a语意。
  • 组成:一个类和另一个类是关联的,两个类之间是整体和部分的关系,是一种has a语意。表现为:持有对方的指针,并占有对方的所有权。
  • 聚合:一个类和另一个类是关联的,两个类之间是整体和局部的关系,是一种has a语意。表现为:持有对方的指针或引用,但不占用对方的所有权。
  • 关联:一个类和另一个类有关联,两个类之间是平等的关系,是一种has a语意。表现为:持有对方的指针或引用,但不占有对方的所有权。
  • 依赖:一个类依赖于另一个类的定义,是一种use a语意。表现为:局部变量、方法参数、静态方法调用等。

类与对象的互动

在分析阶段和设计的早期阶段,开发者主要有两项任务:

  • 从问题域的词汇表中确定出类
  • 创建一些结构,让多组对象一起工作,提供满足问题需求的行为。

这些类和对象统称为问题的”关键抽象“,把这些协作结构称为实现的”机制“。开发者必须关注这些关键抽象和机制的外部视图——代表系统的逻辑框架,包含了系统的类结构和对象结构。

创造高品质的类与对象

如何评判一种抽象的品质:

  • 耦合

一个模块与另一个模块之间建立起的关联强度的测量。继承引入了严重的耦合。

创建松散耦合的类——Demeter法则:类的方法不应该以任何方式依赖于任何类的结构,除了他自己类的当前结构之外,而且每个方法只能够对一个非常有限的类集的对象发出消息。

  • 内聚

内聚测量了单个模块内各个元素的联系程度。尽量减少偶然性内聚,使用功能性内聚——一个类或模式的各元素一同工作,提供某种清晰界定的行为。

  • 充分性

充分指的是类或模块应该记录某个抽象足够多的特征,从而允许有意义的、有效的交互。充分意味着最小接口——缺少某个接口该抽象的意义将不存在。

  • 完整性

完整值得是类或模块的接口记录了某个抽象全部有意义的特征。一个完整的接口以为这该接口包含了某个抽象的所有方向。

  • 基础性

基础性操作就是只有访问该抽象的底层表现形式才能够有效地实现的那些操作。譬如对于一个集合的Add操作必须知道该集合的底层表现形式。而Add四个元素并不是基础性操作。

上面这些选项都是创建类时需要考虑的。对于类的操作,是选择太多的函数还是较少的函数;对于类之间的关系,是采用继承、聚合,还是依赖;对于类之间的交互,如何确定对象之间的可见性——这些都需要进行折中权衡考虑。

面向对象分析

  • 经典方法

根据问题域来源来区分

  • 行为分析

将对象的行为作为类和对象的主要来源

  • 领域分析

将领域分析定义为“确定对象、操作和关系的尝试,领域专家认为这些对象、操作和关系对这个领域很重要”。领域分析的步骤如下:

  • 咨询领域专家,构建一个通用的模型草稿
  • 检查领域中原有的系统,以一种通用的格式展示出这方面的理解
  • 咨询领域专家,确定系统间的相似与差异
  • 精化通用模型,以包含原有的系统。

清楚设计问题要做的就是让一名领域专家和一名架构师或开发者进行简短的会晤。——领域专家通常不会是一名开发者,其通常是某个领域的用户。


本文作者:ZeroJiu
本文链接: http://www.freehacker.cn/advanced/ooad/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!