面向对象类关系
- 继承(泛化Generalization) 关系
指的是一个类(称为子类、子接口)继承另外的一个类型(称为父类、父接口)的功能。
- 实现(Realization) 关系
指的是一个类实现一个接口的功能
- 依赖(Dependency) 关系
指两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。在C#中,类A当中使用了类B,其中类B是作为类A的方法参数、方法中的局部变量、或者静态方法调用。
- 关联(Association) 关系
指一个类的实例A使用另外一个类的实例B,这两个对象之间为关联关系。关联关系分为单向关联、双向关联、自关联。
在C#中,单项关联表现为:类A当中使用了类B,其中B作为类A的成员变量。双向关联表现为:类A当中使用了类B作为成员变量;同时类B中也使用了类A作为成员变量。自关联:自身使用自己。
- 聚合(Aggregation) 关系
聚合关系是一种关联关系,耦合度强于关联,它们的代码表现是相同的,仅仅是在语义上有所区别:关联的对象之间是相互独立的,而聚合关系的对象之间存在这包容关系,它们之间是“整体-个体”的相互关系。
- 组合(Compostion) 关系
组合关系也是一种关联关系,其耦合性更强。存在组合关系的类表现为“整体-部分”的关联关系,“整体”负责“部分”的生命周期,它们之间是共生共死的;而且“部分”单独存在时没有意义的。
面向对象设计原则
- 单一职责原则
这里的职责是指类变化(类成员的变化,如行为方法、属性访问器、字段变量等等成员)的原因。本原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。
违背该原则,会存在以下两个缺点:
1、一个职责的变化可能会削弱或者一直这个类实现其他职责的能力;
2、当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费。
遵守该原则,则存在以下优点:
1、降低类的耦合度。
2、提高可读性。
3、提高系统的可维护性。
4、修改引发的风险降低。单一职责原则是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。
- 开放关闭原则
这是面向对象原则的核心。我们开发的系统、框架、代码,尽可能通过扩展的方式去实现新功能,而不要修改原有的代码。
如何开发才不违背开闭原则呢?
可以通过“抽象约束,封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实体类中。
- 接口分离原则
要为各个类建立它们需要的专用接口;而不要试图去建立一个很庞大的接口,供所有依赖它的类去调用。
接口隔离原则和单一职责原则都是为了提高类的内聚性、降低类之间的耦合性,体现了封装的思想。不同之处为:
1、单一职责原则注重的职责,而接口分类原则注重的是对接口依赖的隔离;
2、单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口分类原则主要约束接口,主要针对抽象和程序整体框架的构建。
如何开发才不违背接口分离原则呢?
1、接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑;
2、为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法;
3、了解环境,绝决盲从。每个项目或产品都有选定的环境因素。环境不同,接口拆分的标准就不同;
4、提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
- 里氏替换原则
官方定义
一、如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
二、所有引用基类的地方必须能透明地使用其子类的对象
里氏替换原则强调的是设计和实现要依赖于抽象,而非具体;子类只能去扩展基类,而不是隐藏或者覆盖基类。它包含以下4层含义:
1、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
2、子类可以有自己的个性;
3、覆盖或实现父类的方法时,输入参数可以被放大;
4、覆写或实现父类的方法时,输出结果可以被缩小。
里氏替换原则的优点
保证了父类的复用性;同时也能降低系统出现故障,防止误操作;同时也不会破坏继承的机制,这样继承才显得更有意义。
增强程序的健壮性;版本升级时,也可以保证非常好的兼容性。即使增加子类,原有的子类还可以继续运行。在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑。
- 依赖倒置原则
定义
依赖倒置原则指的是高层模块(稳定)不应该依赖于底层模块(变化),二者都应该依赖于抽象(稳定)。抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。
依赖倒置原则的好处
1、减少类之间的耦合性,提高系统的稳定性
2、降低并行开发引起的风险
3、提高代码的可读性和可维护性
- 迪米特原则(最少知道原则)
定义
Law of Demeter.一个对象应该对其他对象保持最少的了解。
迪米特原则的优点
1、使得软件更好的可维护性与适应性;
2、对象较少依赖其他对象的内部结构,可以改变对象容器(container),而不用改变它的调用者(caller)。
- 组合/聚合复用原则
定义
Composite/Aggregate Reuse Principle.也叫合成复用原则。组合/聚合复用原则是指尽量使用组合/聚合,不要使用类继承。
组合/聚合复用原则好处
1、可以降低类与类之间的耦合程度
2、提高系统的灵活性
面向对象特征
-
继承
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”。 被继承的类称为“基类”、“父类”或“超类”。 继承的过程,就是从一般到特殊的过程。 要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。 在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。 继承概念的实现方式有三类:实现继承、接口继承和可视继承。 Ø 实现继承是指使用基类的属性和方法而无需额外编码的能力; Ø 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力; Ø 可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。 在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。 抽象类仅定义将由子类创建的一般属性和方法,创建抽象类时,请使用关键字 Interface 而不是 Class。 OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。 -
封装
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 -
多态
参考地址
多态性介绍(微软官方文档)
面向对象分析
-
建立用例模型
-
建立对象模型
-
建立动态模型
面向对象设计
- 创建型设计模式
简单工厂模式、抽象工厂模式、建造者模式、原型模式、单例模式
- 结构型设计模式
适配器模式、外观模式、桥接模式、组合模式、装饰者模式、享元模式、代理模式
- 行为型设计模式
中介者模式、观察者模式、迭代器模式、责任链模式、访问者模式、模板模式、命令模式、策略模式、备忘录模式、状态模式、解释器模式