一、面向对象基础
1、基本概念
(1)对象
对象是由数据及其操作所构成的封装体,是系统中用来描述客观事务的一个实体,是构成系统的一个基本单位。一个对象通常可以由对象名、属性和方法3个部分组成。
(2)类
类是定义了一组大体上相似的对象,是现实世界中实体的形式化描述。类是对象的抽象,对象是类的实例化。
类可以分为三种:实体类、接口类和控制类。
(3)类的特性
【1】封装
是一种信息隐藏技术。面向对象的封装是将数据和其操作封装成一个整体对象。
【2】继承
是类之间的层次关系(父类与子类),这种关系使得某类对象可以继承另外一类对象的特征。可分为单继承和多继承。
【3】多态
描述的是不同对象收到同一个消息时会产生完全不同的结果。包括:
参数多态:不同类型参数,多种结构类型
包含多态:父子类型关系
过载多态:类似重载,一个名字不同含义
强制多态:强制类型转换
(4)覆盖
在子类中重新定义一个与父类同名同参数的方法。
(5)重载
函数名相同,但是参数不同的多个方法。
(6)绑定
绑定时一个把过程调用和响应调用所需要执行的代码加以结合的过程。
静态绑定:在编译时进行的
动态绑定:在运行时进行的
2、面向对象分析
面向对象分析包含 5 个活动:认定对象、组织对象、描述对象间的相互作用、确定对象的操作、定义对象的内部信息。
3、面向对象设计
面向对象设计是将 OOA 所创建的分析模型转化为设计模型,其目标是定义系统构造蓝图。
面向对象设计原则
(1)单一责任原则。就一个类而言,应该仅有一个引起它变化的原因。即,当需要修改某个类的时候原因有且只有一个,让一个类只做一种类型责任。
(2) 开放-封闭原则。软件实体(类、模块、函数等)应该是可以扩展的,即开放的;但是不可修改的,即封闭的。
(3)里氏替换原则。子类型必须能够替换掉他们的基类型。即,在任何父类可以出现的地方,都可以用子类的实例来赋值给父类型的引用。当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有是一个(is-a) 关系。
(4)依赖倒置原则。抽象不应该依赖于细节,细节应该依赖于抽象。即,高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
(5) 接口分离原则。不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。即:依赖于抽象,不要依赖于具体,司时在抽象级别不应该有对于细节的依赖。这样做的好处就在于可以最大限度地应对可能的变化。
(6) 重用发布等价原则。重用的粒度就是发布的粒度。
(7)共同封闭原则。包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。
(8)共同重用原则。一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
(9) 无环依赖原则。在包的依赖关系图中不允许存在环,即包之间的结构必须是一个直接的五环图形。
(10) 稳定依赖原则。朝着稳定的方向进行依赖。
(11)稳定抽象原则。包的抽象程度应该和其稳定程度一致。
4、面向对象程序设计
面向对象程序设计的实质是选用一种面向对象程序设计语言,采用对象、类及其相关概念所进行的程序设计。
5、面向对象测试
一般来说,对面向对象软件的测试可分为下列 4 个层次进行。
(1) 算法层。测试类中定义的每个方法,基本上相当于传统软件测试中的单元测试。
(2)类层。测试封装在同一个类中的所有方法与属性之间的相互作用。在面向对象软件中类是基本模块,因此可以认为这是面向对象测试中所特有的模块测试。
(3) 模板层。测试一组协同工作的类之间的相互作用,大体上相当于传统软件测试中的集成测试,但是也有面向对象软件的特点(例如,对象之间通过发送消息相互作用)。
(4)系统层。把各个子系统组装成完整的面向对象软件系统,在组装过程中同时进行测试。
二、UML
统一建模语言是面向对象软件的标准化建模语言。UML由3个要素构成:UML基本构造块、支配这些构造块如何放置在一起的规则和运用与整个语言的一些公共机制。
UML词汇表包含3中构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。
1、事物
UML 中有 4 种事物:结构事物、行为事物、分组事物和注释事物。
(1)结构事物。结构事物是 UML 模型中的名词。它们通常是模型的静态部分描述概念或物理元素。结构事物包括类、接口、协作、用例、主动类 、构件、制品和结点。
(2)行为事物。行为事物是 UML 模型的动态部分。它们是模型中的动词,描述了跨越时间和空间的行为。行为事物包括交互、状态机和活动。
(3)分组事物。分组事物是 UML 模型的组织部分,是一些由模型分解成的“盒子”。在所有的分组事物中,最主要的分组事物是包。包是把元素组织成组的机制,这种机制具有多种用途。
(4)注释事物。注释事物是 UML 模型的解释部分。这些注释事物用来描述、说明和标注模型的任何元素。注解是一个依附于一个元素或者一组元素之上,对它进行约束或解释的简单符号。
2、关系
UML 中有 4种关系: 依赖、关联、泛化和实现。
(1)依赖。依赖是两个事物间的语义关系,其中一个事物(独立事物) 发生变化会影响另一个事物(依赖事物) 的语义。在图形上,把一个依赖画成一条可能有方向的虚线。
(2)关联。关联是一种结构关系,它描述了一组链,链是对象之间的连接聚集是一种特殊类型的关联,它描述了整体和部分间的结构关系。
(3)泛化。泛化是一种特殊/一般关系,特殊元素(子元素) 的对象可替代一般元素(父元素) 的对象。在图形上,把一个泛化关系画成一条带有空心箭头的实线,它指向父元素。
(4)实现。实现是类元之间的语义关系,其中一个类元指定了由另一个类元保证执行的契约。在两种情况下会使用实现关系:一种是在接口和实现它们的类或构件之间;另一种是在用例和实现它们的协作之间。在图形上,把一个实现关系画成一条带有空心箭头的 虚线。
3、图
图是一组元素的图形表示。UML 2.0 提供了 13 种图,分别是类图、对象图、用例图、序列图、通信图、状态图、活动图、构件图、组合结构图、部署图、包图、交互概览图和计时图。序列图、通信图、交互概览图和计时图均被称为交互图。
【1】类图:展现了一组对象、接口、协作和它们之间的关系。类图给出系统的静态设计视图。
依赖关系:一个事物发生变化影响另一个事物。
泛化关系:特殊/一般关系
关联关系:描述了一组链,链是对象之间的连接。
聚合关系:整体与部分生命周期不同。 部分脱离整体可存在
组合关系:整体与部分生命周期相同。 部分脱离整体消失
实现关系:接口与类之间的关系
【总结记忆:菱形需看头,实成和空聚;三角要看线,实泛虚实现;箭头还看线,虚赖实关联】
【2】对象图:展现了某一时刻一组对象以及他们之间的关系,描述了在类图中所建立的事物的实例的静态快照。对象图一般包括对象和链。对象图也给出系统的静态设计视图。
【3】用例图:展现了一组用例、参与者以及它们之间的关系。其展示的是该系统在它的外面环境中所提供的外部可见服务。用例图的关系有两种:扩展关系《extend》、包含关系《include》。
包含关系:其中这个提取出来的公共用例称为抽象用例,而把原始用例称为基本用例或基础用例:当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示它们。
扩展关系:如果一个用例明显地混合了两种或两种以上的不同场景,即根据情况可能发生多种分支,则可以将这个用例分为一个基本用例和一个或多个扩展用例,这样使描述可能更加清晰。
【4】交互图:用于对系统的动态方面进行建模。一张交互图由一组对象和它们之间的关系组成,包含它们之间可能传递的消息。交互图表现为序列图、通信图、交互概览图和计时图。
序列图是强调消息时间顺序的交互图;
通信图是强调接收和发送消息的对象的结构组织的交互图;
交互概览图强调控制流的交互图。
计时图描述对象状态随着时间改变的情况,适合分析周期和非周期性任务。
【5】状态图:展现了一个状态机,它由状态、转换、事件和活动组成。状态图强调对象行为的事件顺序。其通常包括简单状态和组合状态、转换(事件和动作)。
状态是指对象的生命周期中某个条件或者状态,是对象执行了一系列活动的结果,当某个事件发生后,对象的状态将发生变化。
嵌套在另外一个状态中的状态称为子状态,含有子状态的状态称为组合状态。
转换是两个状态之间的种关系,表示对象将在源状态中执行一定的动作,并在某个特定事件发生而且某个特定的警界(监护)条件满足时进入目标状态。
动作是一个可执行的原子操作,是不可中断的。
【6】活动图:是一种特殊的状态图,它展现了在系统内从一个活动到另一个活动的流程。活动图专注于系统的动态视图,强调对象间的控制流程。
【7】构件图:展现了一组构件之间的组织和依赖。构件图专注于系统的静态实现视图。
【8】组合结构图:用于描述一个分类器 (如类、构件或用例)的内部结构,分类器与系统中其他组成部分之间的交互端口,展示一组相互协作的实例如何完成特定的任务,描述设计、架构模式或策略。
【9】部署图 :是用来对面向对象系统的物理方面建模的方法,展现了运行时处理结点以及其中构件(制品)的配置。部署图对系统的静态部署视图进行建模,它与构件图相关。
【10】包图 :展现由模型本身分解而成的组织单元以及其间的依赖关系。包可以拥有其他元素,可以是类、接口、构件、结点、协作、用例和图,甚至是嵌套的其他包。一个元素只能被一个包所拥有,拥有关系的包形成了一个命名空间,其中同一种元素的名称必须唯一。
三、设计模式
1、要素
4个基本要素:模式名称、问题、解决方案、效果。
设计模式确定了所包含的类和实例,它们的角色、协作方式以及职责分配。每一个设计模式都集中于一个特定的面向对象设计问题或设计要点,描述了什么时候使用它,在另一些设计约束条件下是否还能使用,以及使用的效果和如何取舍。按照设计模式的目的可以分为三大类。
2、创建型设计模式
创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。
该模式允许用结构和功能差别很大的“产品”对象配置一个系统。配置可以是静态的 (即在编译时指定),也可以是动态的 (在运行时)。
设计模式名称 | 简要说明 | 速记关键字 |
Factory Method 工厂方法 | 定义一个创建对象的接口,但由子类决定需要实例化哪一个类。 工厂方法使得子类实例化的过程推迟 | 动态生产对象 |
Abstract Factory 抽象工厂 | 提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类 | 生产成系列对象 |
Builder 生成器 | 将一个复杂类的表示与其构造相分离,使得相同的构建过程能够得出不同的表示 | 复杂对象构造 |
Prototype原型 | 用原型实例指定创建对象的类型,并且通过拷贝这个原型来创建新的对象 | 克隆对象 |
Singleton单例 | 保证一个类有一个实例,并提供一个访问它的全局访问点 | 单实例 |
(1)工厂方法
1、意图
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。【实例化延迟到子类】
2、实用性
① 当一个类不知道它所必须创建的对象类的时候;
② 当一个类希望由它的子类来指定它所创建的对象的时候;
③ 当类将创建对象委托给子类的某个时候。
(2)抽象工厂
1、意图:
提供一个创建一系列**相关或相互依赖对象的接口,而无需指定它们具体的类。
2、适用性
① 一个系统要独立于它的产品的创建、组合和表示时
② 一个系统要由多个产品系列中的一个来配置时
③ 当要强调一系列相关的产品对象的设计一边进行联合使用时
④ 当提供一个产品类库,只想显示他们的接口而不是实现时
(3)生成器模式
1、意图
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
2、适用性
① 当创建复杂对象的算法应该独立于该对象的组成部分以及其装配方式时
② 当构造过程必须允许被构造的对象有不同的表示时
(4)原型模式
1、意图
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象
2、适用性
① 当一个系统应该独立于它的产品创建、构成和表示时
② 当要实例化的类是在运行时刻指定时,例如,通过动态装载
③ 为避免创建一个与产品类层次平行的工厂类层次时
④ 当一个类的实例只能有几个不同状态组合中的一种时。
3、结构型模式
设计模式名称 | 简要说明 | 速记关键字 |
Adapter适配器 | 将一个类的接口转换成另一种接口。使原本不相容的接口得以协同工作 | 转换接口 |
Bridge桥接 | 将类的抽象部分和它的实现部分分离开来,使它们可以独立地变化 | 继承树拆分 |
Composite组合 | 将对象组合成树型结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性 | 树形目录结构 |
Decorator装饰 | 动态地给一个对象添加一些额外职责。它提供了用子类扩展功能的一个灵活的替代,比派生一个子类更加灵活 | 动态附加职责 |
Facade外观 | 定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用 | 对外统一接口 |
Flyweight享元 | 提供支持大量细粒度对象共享的有效方法 | 汉字编码 |
Proxy代理 | 为其他对象提供一种代理以控制这个对象的访问 | 快捷方式 |
(1)适配器模式Adapter
1、意图
将一个类的接口转换成另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2、适用性
① 想使用一个已经存在的类,但其接口不符合要求
② 想创建一个可以复用的类,该类可以与其他布线管的类或者不可预见的类协同工作。
③ (仅适用于对象Adapter )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
(2)桥接模式bridge
1、意图
将抽象部分与其实现部分相分离,使它们都可以独立地变化
2、适用性
① 不希望在抽象和它的实现部分之间有一个固定的绑定关系。
② 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。
③ 对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译。
④ 有许多类要生成的类层次结构。
⑤ 想在多个对象间共享实现,但同时要求客户并不知道这一点。
(3)组合模式Compsite
1、意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Compsite使得用户对单个对象和组合对象的使用具有一致性。
2、适用性
① 想表示对象的部分-整体层次结构。
② 希望忽略组合对象与单个对象的不同,统一地使用组合结构中所有对象。
(4)装饰模式Decorator
1、意图
动态的给一个对象添加一些额外的职责。
2、适用性
① 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
② 处理那些可以撤销的职责。
③ 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。
(5)享元模式Flyweight
1、意图
运用共享技术有效地支持大量细粒度的对象。
2、适用性
① 一个应用程序使用了大量的对象。
② 完全由于使用大量的对象,造成很大的存储开销。
③ 对象的大多数状态都可变为外部状态。
④ 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
⑤ 应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
4、行为型模式
行为模式设计算法和对象间职责的分配。行为模式不仅描述对象或类的模式,还描述他们之间的通信模式。
行为类模式使用继承机制在类间分派行为。行为对象模式使用对象复合而不是继承。
设计模式名称 | 简要说明 | 速记关键字 |
Chain of Responsibility职责链模式 | 通过给多个对象处理请求的机会,减少请求的发送者与接收者之间的耦合。将接收对象链接起来,在链中传递请求,直到有一个对象处理这个请求 | 传递职责 |
Command命令模式 | 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作 | 日志记录,可撤销 |
Interpreter解释器模式 | 给定一种语言,定义它的文法表示,并定义一个解释器,该解释器用来根据文法表示来解释语言中的句子 | 虚拟机的机制 |
Iterator迭代器模式 | 提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示 | 数据集 |
Mediator中介者模式 | 用一个中介对象来封装一系列的对象交互。它使各对象不需要显式地相互调用,从而达到低耦合,还可以独立地改变对象间的交互 | 不直接引用 |
Memento备忘录模式 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的状态 | 游戏存档 |
Observer观察者模式 | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新 | 联动 |
State状态模式 | 允许一个对象在其内部状态改变时改变它的行为 | 状态变成类 |
Strategy策略模式 | 定义一系列算法,把它们一个个封装起来,并且使它们之间可互相替换,从而让算法可以独立于使用它的用户而变化 | 多方案切换 |
Template Method模板方法模式 | 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤 | 框架 |
Visitor访问者模式 | 表示一个作用于某对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作 | 数据与操作分离 |
(1)命令模式Command
1、意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作
2、适用性
① 抽象出待执行的动作以参数化某对象。
② 在不同的时刻指定、排列和执行请求。
③ 支持取消操作。
④ 支持修改日志。
⑤ 用构建在原语操作上的高层操作构造一个系统。
(2)观察者模式Observer
1、意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
2、适用性
① 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
② 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
③ 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
(3)状态模式State
1、意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
2、适用性
① 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
② 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
(4)策略模式Strategy
1、意图
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
2、适用性
许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
四、总 结
笔记总结不易,如果喜欢,请关注、点赞、收藏。
完整笔记下载地址:(后续完成后更新)
基础精讲课件地址:(请关注、点赞、收藏后,私信我)
基础精讲视频地址:(请私信我)