面向对象设计原则及设计模式简介
面向对象不能只停留在OOP(面向对象开发),要学会OOD(面向对象设计),甚至OOA(面向对象分析),否则只能当CRUD的码农。
面向对象设计原则
单一职责原则(Single Responsibility Principle, SRP)
定义一:一个对象应该只包含单一的职责,并且该职责被完整的封装在一个类中。
定义二:就一个类而言,应该仅有一个引起它变化的原因。
开闭原则(Open-Closed Principle, OCP)
定义:一个软件实体应当对扩展开放,对修改关闭。
里氏代换原则(Liskov Substitution Principle, LSP)
定义一:如果对每一个类型为S
的对象o1
,都有类型为T
的对象o2
,使得以T
定义的所有程序P
在所有的对象o1
都代换o2
时,程序P
的行为没有变化,那么类型S
是类型T
的子类型。
定义二:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
通俗表达:在软件中如果能够使用基类对象,那么一定能够使用其子类对象。把基类都替换成它的子类,程序将不会产生任何错误和异常;反之不成立,即如果软件实体中使用的是子类,则它不一定能够使用基类。
使用里氏代换原则时的注意事项
- 子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法;
- 在运用里氏代换原则时,尽量把父类设计为抽象类或接口,让子类继承父类或实现父接口,并实现在父类中声明的方法。
依赖倒转原则(Dependence Inversion Principle, DIP)
定义一:高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
定义二:要针对接口编程,不要针对实现编程。
依赖倒转原则中的两个概念
类之间的耦合
- 零耦合:两个类之间没有任何耦合关系。
- 具体耦合:发生在两个具体类(可实例化的类)之间,由一个类对另一个具体类实例的直接引用产生。
- 抽象耦合:发生在一个具体类和一个抽象类之间或两个抽象类之间,使两个发生关系的类之间存有最大的灵活性。由于抽象耦合中至少有一端是抽象的,故可以通过不同的具体实现来进行扩展。
依赖注入(Dependence Injection, DI)
依赖注入就是将一个类的对象传入另一个类,注入时应该尽量注入父类对象,在程序运行时再通过子类对象来覆盖父类对象。
依赖注入的三种方式:
- 构造注入(Constructor Injection):通过构造函数注入实例变量。
- 设值注入(Setter Injection):通过Setter方法注入实例变量。
- 接口注入(Interface Injection):通过接口方法注入实例变量。
接口隔离原则(Interface Segregation Principle, ISP)
定义一:客户端不应该依赖那些它不需要的接口。
定义二:一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。
合成复用原则(Composite Reuse Principle, CRP)
又称组合/聚合复用原则(Composite/ Aggregate Reuse Principle, CARP)
定义:尽量使用对象组合,而不是继承来达到复用的目的。
简言之就是,要尽量使用组合/聚合关系,少用继承。在软件开发中,一般首选使用组合/聚合来实现复用,其次才考虑继承。使用继承时应严格遵循里氏代换原则,有效使用继承有助于解决问题,降低复杂度,而滥用继承反而会增加系统的构建和维护的难度。
迪米特法则(Law of Demeter, LoD)
又称最少知识原则(Least Knowledge Principle, LKP)
定义一:不要和“陌生人”说话。
定义二:只与你的直接朋友通信。
定义三:每个软件单元对其他的单元都只有最少的知识,而且局限于那些与本单元密切相关的软件单元。
在迪米特法则中,对于一个对象,它的朋友包括
- 当前对象本身(unit);
- 以参数形式传入到当前对象方法中的对象;
- 当前对象的成员对象;
- 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
- 当前对象所创建的对象。
使用迪米特法则时的注意事项
- 在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;
- 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;
- 在类的设计上,只要有可能,一个类型应当设计成不变类;
- 在对其他类的引用上,一个对象对其他对象的引用应当降到最低。
GoF设计模式简介
范围/目的 | 创建型模式 | 结构型模式 | 行为型模式 |
---|---|---|---|
类模式 | 工厂方法模式 | 适配器模式(类) | 解释器模式 模板方法模式 |
对象模式 | 抽象工厂模式 建造者模式 原型模式 单例模式 |
适配器模式(对象) 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 |
职责链模式 命令模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 访问者模式 |
创建型模式:主要用于创建对象。
结构型模式:主要用于处理类或对象的组合。
行为型模式:主要用于描述对类或对象怎样交互和怎样分配职责。
面向对象设计原则及设计模式简介