1 )类: 是对一组对象的描述,这些对象具有相似的属性、操作、关系和行为。
是对某种类型的对象定义属性和方法的原型,表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。具有相同数据结构和行为的对象被分组为一个类。
2 )对象: 对象是人们进行研究的任何事物,不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
对象可以改变自身的状态,对象具有对世界作出决定和反应的能力,对象具有一定的特征和行为
3 ) OO 特色:继承、封装、多态。
4 )不同视角描述系统的三种模型:类模型( 描述系统内部对象及其关系 。。。 系统静态的、结构化的“数据”层面, 描述系统中对象的结构 — 它们的标识、与其他对象的关系、属性和操作 )、状态模型( 描述对象生命历史。。。 系统时序的、行为的“控制”层面, 描述了与操作的时间和顺序相关的对象层面 — 标记变化的时间,界定事件上下文的状态,以及事件和状态的组织 )、交互模型( 描述对象之间交互。。。 表示独立对象的协作,系统的“交互”层面,描述对象之间的交互 — 独立对象如何协作,来从整体上完成系统的行为 )
5 )三种模型的关系:类模型描述状态模型和交互模型操作的数据结构。类模型中的操作对应于事件和动作。状态模型描述对象的控制结构。它显示了依赖于对象取值的决策,并引发动作来改变对象取值和状态。交互模型专注于对象之间的信息交互,并提供了系统操作的整体视图。
UML 和面向对象软件开发之间有很强的关联关系,甚至可以说是面向对象软件开发催生了 UML 。 UML 的标准化和发展过程,有机地吸纳了业务建模、工作流建模、数据库建模等领域的标准规范,形成了一个适用性很强的标准。面向对象是一种软件开发思想, UML 则是用于表达这种思想的语言
– UML 是对描述面向对象的系统分析和设计工作所用符号进行标准化尝试的一种语言
– 其目的是建立一套不依赖于完成设计所用方法的符号
– UML 的开发意图是用于所有面向对象的开发方法、生命循环阶段、应用程序
– UML 未定义标准过程,而是为迭代开发过程提供帮助
1 ) UML9 种图:类图、对象图、(类模型 — 静态模型);状态图(状态模型 — 动态模型);
顺序图、 用例图、协作图、活动图(交互模型);组件图、部署图(实现模型);
具体分类如下:
静态图:类图、对象图、部署图、组件图、用例图
动态图:状态图、活动图、协作图、 顺序图 。。。
动态模型 : 描述了系统与操作时间和顺序有关的系统方面、影响更改的事件,事件的序列,事件的环境以及事件的组织。
2 ) UML 概念: 统一建模语言,为面向对象开发系统的产品进行说明、可视化和编制文档的一种标准语言。 为面向对象软件设计提供统一的、可视化、标准的建模语言。
3 ) UML 的三个特征: UML 是一种语言,是用来建模的,是统一的标准
4 ) 面向对象建模过程是通过应用面向对象的思维,分析、设计和实现系统的过程
分析:通过构造模型来更加深入地理解需求。分析的目标就是要确定应该完成哪些内容,而不是确定如何完成这些内容。在尝试解决问题之前必须先理解问题。分析分为领域分析和应用分析两个子阶段。
设计:系统设计 和类设计,系统设计是为了解决应用问题而设计一个高层策略—架构,制定政策以后指导后续的类设计。类设计扩充并调整从分析当中得到的真实模型,以使它们易于进行计算机实现,其次决定实现这些操作的算法。
’
. 面向对象技术的相关原则:抽象、封装、分解、泛化、多态、分层、复用
. UML的内涵:
UML — Unified Modeling Language
不是一种程序设计语言,而是一种可视化的建模语言(用于分析设计)
不是工具或知识库的规格说明,而是一种建模语言规格说明,是一种模型表示的标准
不是过程,也不是方法,但允许任何一种过程和方法使用它
用例视图(是被称为参与者的外部用户所能观察到的系统功能的模型图)-面向用户
逻辑视图:面向系统分析 和设计人员
进程视图:面向系统集成人员
实现视图:又叫开发视图,面向编码人员
部署视图:又叫物理视图,面向系统工程师
(1) 依赖是两个事物间的弱语义关系, 表明两个事物之间存在着一种使用关系, 其中
一个事物(独立事物)发生变化会影响另一个事物(依赖事物)的语义。
依赖的表现形式:一个类作为另一个类的方法参数或者返回类型,或者方法中使用到了另一个类的对象。
(2) 关联是一种强语义联系的结构关系,表明两个事物之间存在着明确的、稳定的语
义联系。所谓的静态,即指只要两个对象存在,他们的关联关系即存在,不会因对象状态的不同而有所变化。
关联具有多重性 ,表示多少个对象参与了某个关联。
注意和 多重关联 区别:多重关联举例,学生和导师既可以是老师关系也可是朋友关系。
关联终端名:关联的两端需要名字来加以识别,特别是对于同一个类的两个对象之间的关联是必须的,他们可以区分一对类之间的多重关联。
如何避免多重关联:将关联上升为关联类。 注意理解关联类和普通类。
(3) 泛化是一种特殊/一般关系,特殊元素(子元素)的对象可替代一般元素(父元素)
的对象。泛化具有“代码复用”、“支持多态”“结构化描述对象”,6泛化出现了父类,继承出现了子类。泛化和特化是相反的过程。
(4) 实现是两个事物是之间的一种契约关系,其中的一个事物(箭头指向的事物)描述了另一个事物必须实现的契约。
(5)组合:特殊的关联,关联两端存在整体和部分的关系,如 书房—书桌
(6)聚合:特殊的关联,更强的一种聚合,关联两端不但存在整体和部分的关系,而且整体和部分是具有相同的生命周期,而且一个部件只能属于一个装配件,如车窗户—玻璃。聚合具有传递性和反对称性。
静态(7种):类图、对象图、构件图、部署图、包图、组合结构图、外廓图
动态(7种):顺序图、通信图、时间图、交互纵览图、活动图、状态机图、用例图
UML的重要内容可以由哪五类图(共9种图形)来定义:
用例图:用例图。
静态图:类图、对象图
行为图:状态图、活动图
交互图:时序图(顺序图)、协作图(通信图)
实现图:构件图、部署图
类图:类图是描述类、接口、协作以及它们之间的关系的图,用来显示系统中各个类的静态结构。
类包括:类图、属性、方法。
类图包括:类、接口、协作、关系、约束、注释以及包。
类的表示包括:名称、属性、操作、职责和约束。
类图的建模过程:确定对象与类、确定类的属性、确定类的关系。
类图在UML中的重要作用:
1.为开发人员提供这种模仿现实世界的表达方式。
2.让分析员使用客户所采用的术语和客户交流,
促使客户说出所要解决的问题的重要细节。
对象图:对象图表示在某一时刻一组对象以及他们之间的关系的图。
UML对象图的用途:
◆捕获实例和连接、
◆在分析和设计阶段创建、
◆捕获交互的静态部分、
◆举例说明数据/对象结构、
◆详细描述瞬态图、
◆由分析人员、设计人员和代码实现人员开发
用例图:表述了一组用例、参与者以及它们之间的关系的图。
用例模型包括:用例图和用例规则。
用例规则包括:基本流和备选流。
用例图的组成元素有:参与者,用例,通信关联。
用例规约建立用例模型步骤:
1)根据系统边界确定参与者
2)根据每个参与者确定与之相关联的用例
3)对每个用例写出用例规约文档,调整用例模型(优化参与者与参与者之间的关系,用例与用例之间的关系)
用例对于系统开发人员来说的价值:是用来从用户的观察角度收集系统需求的一项技术,便于分析员与客户和用户交流,使系统更符合用户的需求
顺序图也称为时序图,它描叙了系统中对象间通过消息进行的交互,强调了消息在时间轴上的先后顺序。
顺序图是由对象、生命线、控制焦点和消息等构成。(消息表示了对象间的通信,生命线表示了对象的生存期,控制焦点表示对象正在执行一些活动)
顺序图将交互关系表示为一张二维图,其中纵向是时间轴,时间沿竖线向下延伸,横向代表了在协作中各独立对象的角色。
顺序图中从左到右各对象分别为:执行者角色、控制类、用户接口、业务层、后台数据库。
顺序图的作用:顺序图常用来描述用例的实现,它表明了由哪些对象通过消息相互协作来实现用例的功能。在顺序图中,标识了消息发生的先后顺序。
协作图:描述了系统中对象间通过消息进行的交互,强调了对象在交互行为中承担的角色。协作图包括对象、链(连接器)、消息。
(协作图与顺序图的比较与各自的优缺点下面有)
交互图(协作图与顺序图)的特征:
交互图形主要用于对用例中的控制建模,一般情况下,一个交互图形表达单个用例的行为,它表示出该用例中若干个实例对象和对象之间所传递的消息,交互图形有效的帮助人们观察和理解系统内部的协作关系和过程行为。
状态图:描述了一个对象所处的可能状态以及状态之间的转换,并给出了状态变化序列的起点和终点。
状态图包括:状态、转换。
一个状态图表示一个状态机,表示从一个状态到另一个状态的控制流。引发状态转换的事件主要有:调用事件、变化事件、时间事件以及信号事件。
建模步骤:找出适合用模型描述其行为的类、 确定对象可能存在的状态、确定引起状态转换的事件、确定转换进行时对象执行的相应动作、对建模结果进行相应的精化和细化。
作用:能帮助分析员、设计员和开发人员理解系统中对象的行为。(P87)
活动图:描述从活动到活动的流。
活动图包括:动作状态,活动状态,动作流、分支与合并、分关与汇合、泳道(分区)以及对象流。
构件图:主要用来描述各种软件构件之间的依赖关系,是描述构件与构件关系的图。
构件图包括注释、约束和包。
构件包括5个要素:接口声明、接口实现、构件标准、封装方法以及部署方法。
构件分为3种类型:配置构件、工作产品构件以及执行构件。
构件图的基本目的是:使系统人员和开发人员能够从整体上了解系统的所有物理部件;同时,也使我们知道如何对构件进行打包,以便交付给最终客户;最后,构件图显示了被开发系统所包含的构件之间的依赖关系。
(构件和类的比较见下面)
部署图:描述系统中的硬件节点及节点之间如何连接的图。
部署图的组成元素包括节点、节点间的链接。
部署图的目的:描述系统投产的相关问题;描述系统与生产环境中的其他系统间的依赖关系,这些系统可能是已经存在,或是将要引入的;描述一个商业应用主要的部署结构;设计一个嵌入系统的硬件和软件结构;描述一个组织的硬件/网络基础结构。
范围/目的 | 创建型模式 | 结构型模式 | 行为型模式 |
---|---|---|---|
类模式 | 工厂方法 | (类)适配器 | 模板方法、解释器 |
对象模式 | 单例 原型 抽象工厂 建造者 |
代理 (对象)适配器 桥接 装饰 外观 享元 组合 |
策略 命令 职责链 状态 观察者 中介者 迭代器 访问者 备忘录 |
设计模式之间的关系图:
相同功能的代码,不用多次编写,降低冗余
编程规范性, 便于其他程序员的阅读和理解
当需要增加新的功能时,非常的方便,也称为可维护性
当我们增加新的功能后,对原来的功能没有影响
模块内部紧密,但模块间依赖小,一者出错不影响他者
单一职责原则(Single responsibility principle),即一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1、A2。
单一职责原则注意事项和细节
接口隔离原则(Interface Segregation Principle),即客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
比如:类A通过接口I II依赖类B,类C通过接口I II依赖类D,如果接口I II对于类A和类C来说不是最小接口,那么类B和类D必须去实现他们不需要的方法。
按隔离原则应当这样处理:将接口I II拆分为独立的几个接口,将类分别与他们需要的接口建立依赖关系,也就是采用接口隔离原则。
依赖倒转原则(Dependence Inversion Principle),依赖倒转(倒置)的中心思想是面向接口编程,所谓“倒转”是指抽象不应该依赖细节,而是细节应该依赖抽象。也就是高层模块不应该依赖低层模块,二者都应该依赖其抽象。因为相对于细节的多变性,抽象的东西要稳定的多。
比如有个Person类,可以接受Email、QQ和微信的消息。如果都为其提供一个专门的方法,就会让代码非常的冗余:
可以引入一个IReceiver接口,让Person类依赖该接口。这样QQ、微信和Email各自实现IReceiver里面的方法即可:
里氏替换原则(Liskov Substitution Principle)要求所有引用基类的地方必须能透明地使用其子类的对象。也就是在继承关系中,子类尽量不要重写父类的方法。继承实际上让两个类耦合性增强了,特别是运行多态比较频繁的时,整个继承体系的复用性会比较差。
比如一种极端情况:一个类继承了另一个类,但却重写了所有方法,那么继承的意义何在?说好的复用呢?
解决方法是把原来的父类和子类都继承一个更通俗的基类,在适当的情况下,可以通过聚合,组合,依赖等来代替。
开闭原则(Open Closed Principle)一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。也就是当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。用抽象构建框架,用实现扩展细节。
开闭原则是编程中最基础、最重要的设计原则。编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
举个违反开闭原则的例子:
矩形Retangle和圆形Circle继承了图形类Shape(提供方),画图类GraphicEditor(使用方)会调用相关属性。
但是如果再新增一个三角形,就要在使用方GraphicEditor新增对应方法,修改地方较多,违背开闭原则。
改进:把Shape做成抽象类并提供抽象方法draw,让子类去实现即可。当新增图形种类时,只需让新的图形类继承Shape,并实现draw方法即可。使用方的代码就不需要修改,满足开闭原则。
迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好,核心是降低类之间的耦合。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息。
避免与非直接朋友的耦合,只与直接的朋友通信,所谓的直接朋友是出现成员变量,方法参数,方法返回值中的类。而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。
比如有学院员工类和学校员工类,然后各有一个管理类有可以获取其所有员工,学校员工管理类有方法打印全部员工。
业务模型与系统模型之间可能存在的对应关系(详情看P71)
业务模型–》系统模型:
业务用例 -》系统(子系统)
业务参与者 -》系统参与者
业务工人 -》 系统参与者
业务工人的操作(活动) -》 系统用例
业务实体 -》 实体类
共同复用原则(CRP)
共同封闭原则(CCP)
无环依赖原则(ADP)
稳定依赖原则(SDP)
稳定抽象原则(SAP)
<>边界类(系统及其参与者的边界)、
<>控制类(系统的控制逻辑,是整个用例行为的协调器)
<>实体类(系统使用的信息,用于记录系统所需要维护的数据和对这些数据的处理行为)
软件设计的两个独立阶段:1、架构设计2、构件设计
设计元素是指能够直接用于指导实现(编码)的模型元素。针对不同的设计问题和设计目标,可以定义各种不同类型的设计元素。
1、设计类(Design Class):代表一组精确定义的职责集,可以直接用于实现。
PS:设计类可从分析模型分析类中直接获取
2、子系统(Subsystem):代表一组复杂操作的职责集,这些操作最终由其内部的子系统或类实现
3、接口(Interface):代表一组由某个类或子系统所提供职责的抽象声明。
4、主动类(Active Class):代表系统内的控制流程。
架构机制:架构机制是对通用问题的决策、方针和实践。作为系统架构的一部分,架构机制常常集中和定位在系统的非功能需求上
三类架构机制:分析机制(概念)、设计机制(具体)、实现机制(实际)
分析机制用于在分析阶段中向设计人员提供复杂行为的简短表示,从而减少分析的复杂性并提高分析的一致性
进程(Process)是操作系统中的重量级并行执行单元,在自己的空间中独立地运行,为系统提供独立的控制流程。
线程(Thread)则提供轻量级的控制流,它没有独立的运行空间,在所属进程的执行环境和地址空间中运行。
PS:进程与进程之间是依赖关系,进程与线程是组合关系(易错点)
( 1) 当动作结点所有的对象流和控制流的前提条件都满足时,才创建动作的一次执行。
( 2) 根据动作执行所涉及的功能不同,可以划分为不同类别的动作,包括基本功能、
行为调用、通信动作和对象处理等不同类型的动作节点
(1) 活动分区用于识别具有相同特性的一组动作,这些动作被放入相同的区间。
(2) 可以使用不同的分区规则进行分区,并没有严格的规范。
(3) 在业务模型或需求中,往往按照组织机构的单位或系统角色进行分区,一个单位
或角色负责分区中所有节点的行为。而在设计模型中,可以按照不同的类(或构件)进行分
区,一个类(或构件)负责执行该分区中所有节点的行为
\15. 业务模式建模当前业务现状,而系统模型则描述系统中业务实现模式。业务模型还可以为系统模型提供输入。
前置条件是指用例在执行之前必须满足的条件,它约束用例开始执行前系统的状态。作
为用例的入口限制, 前置条件阻止参与者触发该用例直到满足所有条件。
后置条件是指用例执行完成之后系统的状态。当用例存在多个事件流时,可能会对应多
个不同的后置条件。利用后置条件,有助于确保涉众理解执行用例后的结果。
在定义前置条件和后置条件时需要注意,只有在用例的使用者将这些条件视为附加价值
的时候才使用,而且它们均要求是系统可以感知的(或者说检测到的);此外,前置条件还
要求是在用例执行前就可以感知的
用例的涉众是指受用例所代表的业务影响的(或者说与当前用例有利益关系的)系统内
外部人员或组织。由普通的人或部门来承担的参与者一般都是涉众。外部系统、时间等不是
涉众,因为它们不是人或者组织,没有利益影响;不过当有外系统参与者时,那些外系统的
用户往往会作为当前用例的涉众存在
从涉众的角度来看,用例实际上是涉众之间所达成的契约, 并以参与者为达成特定目标
和系统交互的方式演绎。把用例比作一台戏,参与者和系统就是这台戏的演员,而涉众则是
观众,戏的好坏由观众来评价
系统参与者代表了以某种方式与系统交互的人或事。更直观的说, 参与者是指在系统之
外,透过系统边界与系统进行有意义交互的任何事物。识别参与者的主要要点包括:
(1) 系统外:参与者不是系统的组成部分,处于系统的外部;
(2) 系统边界:参与者透过边界直接与系统交互,参与者的确定代表系统边界的确定;
(3) 系统角色:参与者是一个参与系统交互的角色,与使用系统的人和职务没有关系;
(4)与系统交互:参与者与系统交互的过程是系统所需要处理的,即系统职责;
(5) 任何事物:参与者通常是一个使用系统的人,但有时候也可以是一个外系统或外
部因素、时间等外部事物。
分析模型是对分析所形成目标制品的总称;具体来说,分析模型包含两个层次的两类模
型。两个层次是指架构分析和用例分析。两类模型是指静态模型和动态模型。
1)封装性。所谓封装就是把对象的属性和行为结合成一个独立的单位,使外界不能直接访问或修改这些数据和代码,外界只能通过对象提供的接口函数来改变或获取对象的属性数据,这就实现了消息的隐蔽;
2)继承性。如果在一个已定义的类上,增加一些特殊属性或操作,可以形成一个新的类,这个类不仅继承了前一个类的全部特征,
而且具有新的特性,因此可看作前一个类的特例,是对前一个类的继承。前一个类成为父类,新产生的类叫做子类。通过继承关系可形成一种类层次结构,叫做继承结构;
3)多态性。在类层次结构的不同类中,可用相同的函数名实现功能不同的函数。多态即程序中同名的不同方法共存的情况,常见的两种多态方式为:①子类对父类方法的覆盖;②利用重载在同一个类中定义多个同名的不同方法。
为了超越程序复杂性障碍,克服软件危机,人们提出了面向对象软件开发方法。面向对象开发方法一改过去传统的以功能分析为基础的面向过程的结构化分析与设计方法。面向对象开发方法模拟人们理解和处理客观世界的方式来分析问题,把系统视为一系列对象的结合,其面向对象设计又将分析的结果映射到某一种面向对象实现工具的结构上,使映射过程有着比较直接的对应关系,使分析者、设计者和编程者都可使用相同的概念,从而使面向对象的软件开发能比较自然地模拟客观世界的活动,使问题描述空间与解空间在结构上尽可能一致。因此,采用面向对象方法可以更有效地开发大型软件系统。面向对象方法的封装、继承、多态等机制不仅支持软件复用,而且使软件维护工作可靠有效,可实现软件系统的柔性制造,更好地克服软件危机。因此,它成为成熟的广为采用的软件开发方法。
3、分析顺序图和协作图之间的差别和优缺点:
顺序图可视化地表示了对象之间随时间发生的交互,它除了展示对象之间的关联,还显示出对象之间的消息传递。与顺序图一样,协作图也展示对象之间的交互关系。顺序图强调的是交互的时间顺序,而协作图强调的是交互的语境和参与交互的对象的整体组织。顺序图按照时间顺序布图,而协作图按照空间组织布图。顺序图可以清晰地表示消息之间的顺序和时间关系,但需要较多的水平方向的空间。协作图在增加对象时比较容易,而且分支也比较少,但如果消息比较多时难以表示消息之间的顺序。
B-C-E 三层架构是对 MVC 架构的另一种表述,将系统划分为三层,分别处理 3 类业务
逻辑。其中 B 表示边界层,负责处理系统与参与者的交互; C 为控制层,处理系统的控制
逻辑; E 为实体层,负责管理系统使用的信息
多重性表示一个类的对象可能链接到所关联的类的多个对象上,这种“多少”即为关联
角色的多重性,它表示一个整数的范围,通过多重性表达式来指名一组相关对象的可能个数。
需要从关联的另一端来理解多重性的定义,即表明另一端的一个对象可以与本方的多少
个对象相链接
聚合关系是一种特殊的关联关系,除了拥有关联关系所有的基本特征之外,两个关联的
类还分别代表“整体”和“部分”,意味着整体包含部分。
与普通的关联关系相比,关联两端的类要多一层整体和部分的含义,而普通的关联关系
并没有这层含义。
与泛化关系相比,关联是一种包含或拥有的关系,即整体包含或拥有部分;而泛化则是
“是一种”的一般和特殊的关系,子类是一种特殊的父类
可见性是指操作或属性可以被外界访问的程度。 UML 规范定义了四种可见性:公有、
私有、保护和包可见性
操作是类的行为特征,它描述了该类对于特定请求做出应答的规范。
方法是操作的具体实现算法,它描述操作如何实现的流程。
操作描述了类对外提供的接口,是类的外在行为。通过定义操作明确了参数和返回值等
接口细节;而方法则是关注操作内部实现算法的设计
依赖是一种使用关系,表示一个类对象使用另外一个类对象的信息和服务,被使用对象
的变化可能会影响到使用对象。
定义为依赖关系的几种情况:参数引用,局部声明引用和全局引用
用例实现是分析(设计) 模型1中一个系统用例的表达式,它通过对象交互的方式描述了构造用例实现是分析最核心的工作分析(设计)模型中指定的用例是如何实现的。
通过用例实现将用例模型中的用例和分析(设计)模型中的类以及交互紧密联系起来,一个用例实现描述了一个用例需要哪些类来实现,两者之间存在实现关系:即“‘用例实现’实现‘用例’ ”获得实现用例行为所必须的分析类利用这些分析类来描述其实现逻辑
包之间的依赖关系包含两层含义:其一是被依赖包的改变将影响到依赖包;其二则是依
赖包不能够独立的复用,因为它依赖于被依赖包。
除了普通的依赖关系,可以通过构造型进一步扩展不同的依赖关系,如合并、导入和访问