一、面向对象设计的基本概念
https://docs.staruml.io/user-guide/managing-extensions#install-extension
面向对象的分析(OOA):分析需要做的需求。
面向对象的设计(OOD):需要设计那些类、类中设计哪些数据成员、哪些成员函数、类与类之间的关系。
面向对象的编程(OOP):将设计转换为代码
UML语言:统一建模语言
二、类与类之间的关系(==重要==)
1、继承
从派生类向基类画出空间三角箭头。基类会成为派生类的一部分,在语义上:A is B
继承:先有基类,然后再产生派生类。泛化(一般化):先有派生类,然后抽象出基类。
2、关联
2.1、双向的关联关系
在类图的画法上,使用的是实心直线。彼此并不负责对方的生命周期。在语义上:A has B。在代码层面上:使用的是指针或者引用。
2.2、单向的关联关系
在类图的画法上,使用的是实心箭头,从A指向B。彼此并不负责对方的生命周期。在语义上:A has B。在代码层面上:使用的是指针或者引用
3、聚合
表现为整体与局部的关系,整体并不负责局部的生命周期。在类图的画法上,可以从局部指向整体的空心菱形箭头。在语义上:A has B。在代码层面上:使用的是指针或者引用。
4、组合
表现为整体与局部的关系,整体会负责局部对象的销毁。在类图的画法上,使用从局部指向整体的实心菱形箭头。在语义上:A has B。在代码层面上:使用的是子对象的形式
5、依赖
在类图的画法上,使用的是从A指向B的虚线箭头。在语义层面上:A use B。这种关系是偶然的,临时的,并不是固定的。在代码层面上:
- B作为A的成员函数的参数
- B作为A的成员函数的局部变量(返回值)
- A的成员函数调用B的静态方法
总结
1、继承是垂直关系(纵向的关系),其他四种是平行的关系(横向的关系)
2、语义区别:继承是is关系,关联、聚合、组合是has关系,依赖是use关系
3、耦合程度:依赖 < 关联 < 聚合 < 组合 < 继承
4、聚合关系是一种稍强的关联关系,组合关系是一种更强的关联关系,在代码层面上:聚合使用的是指针或者引用,但是组合使用的是子对象
三、面向对象的设计原则(==重要==)
0、总纲
低耦合、高内聚。
低耦合:类与类之间的关系、模块与模块之间的关系。高内聚:类内部或者模块内部之间的关系
1、单一职责原则
核心思想:一个类,最好只做一件事,只有一个引起它变化的原因。
2、开放闭合原则(==重要==)
核心思想:就是对抽象编程,而不对具体编程,因为抽象相对稳定。对扩展开放,对修改关闭。
3、里氏替换原则(==重要==)
核心思想:派生类必须能够替换其基类。
表现形式:
- 派生类可以实现基类的抽象方法,表现为多态(也就是C++中的动态多态)
- 派生类能够新增自己的个性(C++中派生类进行生成的时候,吸收、改造、新增)
- 派生类不能覆盖基类的非抽象方法(C++中隐藏)
4、接口分离原则
核心思想:使用多个小的专门的接口,而不要使用一个大的总接口
5、依赖倒置原则(==重要==)
核心思想:面向接口编程,依赖于抽象(抽象是稳定的,具体的是在变化的)
总结:在大多数情况下,开闭原则、里氏代换原则和依赖倒置原则会同时出现,==开闭原则是目标,里氏代换原则是基础,依赖倒置原则是手段==
6、最少知识原则
核心思想:尽量的降低两个类或者模块之前的耦合关系(解耦)
7、组合复用原则
还是为了降低耦合程度,将继承的写法换成了关联、聚合、组合