【OO】面向对象 01 面向对象方法
面向对象
是软件开发方法,是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。
1 四大特性
- 封装:利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。
setter
、getter
- 继承:代码复用
- 多态:增加代码的灵活度
- 编译时多态,重载
- 运行时多态,重写
- 抽象:忽略一个主题中与当前目标无关的东西,专注于当前目标有关的方面。
- 数据抽象——表示世界中一类事物的特征,就是对象的属性。
- 行为抽象——表示世界中一类事物的行为,就是对象的行为。
2 关系
- 泛化 (Generalization):用来描述继承关系,在 Java 中使用 extends 关键字。
- 实现 (Realization):用来实现一个接口,在 Java 中使用 implements 关键字。
- 聚合 (Aggregation):表示整体由部分组成,但是整体和部分不是强依赖的,整体不存在了部分还是会存在。
- 组合 (Composition):表示整体由部分组成,但是整体和部分是强依赖的,整体不存在了部分也不存在了。
- 关联 (Association):表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。
- 依赖 (Dependency):表示不同类对象之间有关联,依赖关系是在运行过程中起作用的。依赖的形式:
- A 类是 B 类方法的局部变量;
- A 类是 B 类方法的参数;
- A 类向 B 类发送消息,从而影响 B 类发生变化。
3 设计原则
- 单一职责原则(SRP):修改一个类的原因应该只有一个。
- 开放封闭原则(OCP):类应该对扩展开放,对修改关闭。
- 里氏替换原则(LSP):子类对象必须能够替换掉所有父类对象。子类需要能够当成父类来使用,并且需要比父类更特殊。
- 接口分离原则(ISP):不应该强迫客户依赖于它们不用的方法。
- 依赖倒置原则(DIP):高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。具体来说:
- 任何变量都不应该持有一个指向具体类的指针或者引用;
- 任何类都不应该从具体类派生;
- 任何方法都不应该覆写它的任何基类中的已经实现的方法。
- 迪米特法则(LOD):一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。
4 内聚与耦合
内聚:表示内部间聚集、关联的程度。
- 偶然内聚:一个模块内的各处理元素之间没有任何联系,只是偶然地被凑到一起。
- 逻辑内聚:这种模块把几种相关的功能组合在一起,每次被调用时,由传送给模块参数来确定该模块应完成哪一种功能。
- 时间内聚:把需要同时执行的动作组合在一起形成的模块称为时间内聚模块。
- 过程内聚:构件或者操作的组合方式是,允许在调用前面的构件或操作之后,马上调用后面的构件或操作,即使两者之间没有数据进行传递。即如果一个模块内的处理元素是相关的,而且必须以特定次序执行则称为过程内聚。
- 信息内聚:指模块内所有处理元素都在同一个数据结构上操作或所有处理功能都通过公用数据而发生关联。即指模块内各个组成部分都使用相同的数据结构或产生相同的数据结构。
- 顺序内聚:一个模块中各个处理元素和同一个功能密切相关,而且这些处理必须顺序执行,通常前一个处理元素的输出时后一个处理元素的输入。
- 功能内聚:模块内所有元素的各个组成部分全部都为完成同一个功能而存在,共同完成一个单一的功能,模块已不可再分。
耦合:是对模块间关联程度的度量。
- 间接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。耦合度最弱,模块独立性最强。
- 数据耦合:调用模块和被调用模块之间只传递简单的数据项参数。相当于高级语言中的值传递。
- 标记耦合:调用模块和被调用模块之间传递数据结构而不是简单数据,同时也称作特征耦合。
- 控制耦合:模块之间传递的不是数据信息,而是控制信息例如标志、开关量等,一个模块控制了另一个模块的功能。
- 外部耦合:一组模块都访问同一全局简单变量,而且不通过参数表传递该全局变量的信息,则称之为外部耦合。
- 公共耦合:一组模块都访问同一个全局数据结构,则称之为公共耦合。公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。如果模块只是向公共数据环境输入数据,或是只从公共数据环境取出数据,这属于比较松散的公共耦合;如果模块既向公共数据环境输入数据又从公共数据环境取出数据,这属于较紧密的公共耦合。
- 内容耦合:一个模块直接访问另一模块的内容,则称这两个模块为内容耦合。
低耦合,高内聚。就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却要不那么紧密。
5 设计模式
设计模式四个基本要素:模式名称、问题、解决方案、效果。
MVC的主要关系由 Observer、Composite、Strategy 三个设计模式给出。
设计模式怎样解决问题
- 寻找合适的对象:设计模式帮你确定并不明显的抽象和描述这些抽象的对象。
- 决定对象的粒度。
- 指定对象接口:通过确定接口的主要组成成分及接口发送的数据类型,来帮助你定义接口。
- 描述对象的实现。
- 运用复用机制。
- 关联运行时刻和编译时刻的结构。
- 设计应支持变化。
类型 | 设计模式 | 可变的方面 |
---|---|---|
创建型 | 抽象工厂 | 产品对象家族 |
建造者 | 如何创建一个组合对象 | |
工厂模式 | 被实例化的子类 | |
原型 | 被实例化的类 | |
单例 | 一个类的唯一实例 | |
结构型 | 适配器 | 对象的接口 |
桥接 | 对象的实现 | |
组合 | 一个对象的结构和组成 | |
装饰者 | 对象的生成,不生成子类 | |
外观 | 一个子系统的接口 | |
享元 | 对象的存储开销 | |
代理 | 如何访问一个对象;该对象的位置 | |
行为型 | 职责链 | 满足一个请求的对象 |
命令 | 何时、怎样满足一个请求 | |
解释器 | 一个语言的文法及解释 | |
迭代器 | 如何遍历、访问一个聚合的各元素 | |
中介者 | 对象怎样交互、和谁交互 | |
备忘录 | 一个对象中哪些私有信息存放在该对象之外,以及什么时候进行存储 | |
观察者 | 多个对象依赖于另外一个对象,而这些对象又如何保持一致 | |
状态 | 对象的状态 | |
策略 | 算法 | |
模板方法 | 算法中的某些步骤 | |
访问者 | 某些可作用于一个(组)对象上的操作,但不修改这些对象的类 |
设计模式之间的关系
总结
创建型
用一个系统创建的对象的类对系统进行参数化有两种方法
- 生成创建对象的类的子类。缺点在于仅未来改变产品类,就可能需要创建一个新的子类。
- 依赖于对象复合:定义一个负责明确产品对象的类,并将它作为该系统的参数。
结构型
结构型模式依赖于同一个很小的语言机制集合构造代码和对象
- 单继承和多重继承机制用于基于类的模式
- 对象机制用于对象式模式
- 结构类似的模式
- Adapter 与 Bridge 常被用于软件生命周期的不同阶段:Bridge 在设计类之前实施,Adapter 在类设计好后实施。
- Composite 和 Decorator 都基于递归组合来组织可变数目的对象,通常协同使用。
- Decorator 和 Proxy 都描述了怎样为对象提供一定程度上的间接引用。
行为型
各个行为模式之间是相互补充和相互加强的关系。
设计模式带来的影响
- 一套通用的设计词汇
- 书写文档和学习的辅助手段
- 现有方法的一种补充
- 为重构提供了目标