面向对象的设计原则与设计模式

目的

++设计模式的目的是提高代码的重用性,可读性、可扩展性、可靠性,使程序呈现高内聚,低耦合的特性++


++原则++

单一职责原则

假设有一个class负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能会导致另一个职责的功能发生故障。这样一来,这个class就存在两个导致类变更的原因。如何解决这个问题呢?我们就要分别用两个Class来实现两个职责,进行解耦。后期需求变更维护互不影响。这样的设计,可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。

单一职责注意事项:

降低类的复杂度,一个类只负责一项职责;

提高类的可读性,可维护性;

降低变更引起的风险。


依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP) :指设计代码结构时,高层模块不应该依赖底层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。通过依赖倒置,可以降低类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并降低修改程序带来的风险。

依赖倒置原则注意事项:

变量的声明类型尽量是抽象类接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化。

抽象为基准比以细节为基准搭建起来的架构要稳定得多,因此大家再拿到需求后,要面向抽象编程,按照先顶层再细节的顺序设计代码结构。


开闭原则

开闭原则(Open-Closed Principle,OCP) :指一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。强调的是用抽象构建框架,用实现扩展细节,当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化,可以提高软件系统的可复用性及可维护性。

本质:

其本质是指:当在一个设计中增加新的模块时,不需要修改现有的模块。

开闭原则是面向对象设计中最基础的设计原则,他的核心思想是面向抽象编程。


依赖倒置原则与开闭原则的关系:

依赖倒置原则是程序要依赖于抽象接口,不要依赖于具体实现。

当设计某些系统时,经常需要面向抽象来考虑系统的总体设计,不要考虑具体类,这样容易设计出满足"开-闭原则"的系统。

在程序设计好以后,首先要对抽象类(或接口)的修改关闭,否则,一旦修改抽象类(或接口),将可能导致它的所有子类(或实现类)都需要作出修改;应当对增加抽象类的子类(或接口的实现类)开放,即在增加新的子类(或实现类)时,不需要修改其他面向抽象类(或接口)而设计的重要类,例如案例中的Pillar类。


接口隔离原则

接口隔离原则(Interface Segregation Principle, ISP):指用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口。

接口隔离原则注意:

一个类对另一个类的依赖应该建立在最小接口上。

建立单一接口,不要建立庞大臃肿的接口。

尽量细化接口,接口中的方法尽量少(不是越少越好,一定要适度)。


里氏替换原则

里氏替换原则(Liskow Substitution Principle,LSP) :如果对每个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P的所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。

可以理解为一个软件实体如果适用于一个父类,则一定适用于其子类,所有引用父类的地方必须能透明地使用其子类对象,子类对象能够替换父类对象,而程序逻辑不变。也可以理解为,子类可以扩展父类的功能,但不能改变父类原有的功能。


迪米特法则

迪米特法则(Law of Demeter,LoD) :又叫最少知道原则,即一个类对自己依赖的类知道的越少越好,尽量降低类与类之间的耦合。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供public方法,不对外泄露任何信息。

迪米特法则还有个更简单的定义:只与朋友说话,不和陌生人说话。朋友:出现在成员变量、方法参数,方法返回值中的类为直接的朋友,出现在方法体内部的类不属于朋友类。


组合复用原则

组合复用原则(Composite Reuse Principle, CRP) :尽量使用对象组合(has-a)或对象聚合(contains-a)的方法实现代码复用,而不是用继承关系达到代码复用的目的。合成复用原则可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较小

|----------|--------------------------|--------------|
| 设计原则 | 一句话归纳 | 目的 |
| 单一职责原则 | 一个只干一件事 | 便于理解,提高代码可读性 |
| 依赖倒置原则 | 面向抽象 | 降低维护带来的新风险 |
| 开闭原则 | 对扩展开放,对修改关闭 | 更利于代码结构的升级扩展 |
| 接口隔离原则 | 一个接口只干一件事 | 提高内聚,减少对外交互 |
| 里氏替换原则 | 子类重写方法功能发生改变不应该影响父类方法的含义 | 提高代码健壮性及复用性 |
| 迪米特法则 | 不该知道的不要知道 | 解耦,高内聚,低耦合 |
| 组合复用原则 | 尽量是用组合实现代码复用,而不使用继承 | 降低类之间的耦合度 |


设计模式的分类

一般可以按照设计模式的目的(模式是用来做什么的)将其分为创建型(Creational),结构型(Structural)和行为型(Behavioral)3种:

创建型模式:主要用于创建对象

结构型模式:主要用于处理类或对象的组合

行为型模式:主要用于描述对类或对象怎样交互怎样分配职责


创建型模式:

涉及对象的实例化。这类模式的特点是,不让用户代码依赖于对象的创建或排列方式,避免用户直接使用new运算符创建对象。包括:

抽象工厂模式(Abstract Factory)

建造者模式(Builder):又称生成器模式

工厂方法模式(Factory Method)

原型模式(Prototype)

单例模式(Singleton) :又称单件模式


结构型模式:

涉及如何组合类和对象以形成更大的结构,和类有关的结构型模式涉及如何合理地使用继承机制,和对象有关的结构型模式涉及如何合理地使用对象组合机制。包括:

抽象适配器模式(Adapter)

桥接模式(Bridge)

组合模式(Composite)

装饰模式(Decorator)

外观模式(Facade)

享元模式(Flyweight)

代理模式(Proxy)


行为型模式:

涉及怎样合理地设计对象之间的交互通信,以及怎样合理地为对象分配职责,让设计富有弹性、易维护、易复用。包括:

职责链模式(Chain of Responsibility)

命令模式(Command)

解释器模式(Interpreter)

迭代器模式(Iterator)

中介者模式(Mediator)

备忘录模式(Memento)

观察者模式(Observer)

策略模式(Strategy)

状态模式(State)

模板方法模式(Template Method)

访问者模式(Visitor)


简单工厂模式

模式定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂模式的优点

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。

客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。

通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

简单工厂模式的缺点

由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。

系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

相关推荐
犬余42 分钟前
设计模式之享元模式:看19路棋盘如何做到一子千面
java·设计模式·享元模式
机器视觉知识推荐、就业指导11 小时前
C++设计模式:解释器模式(简单的数学表达式解析器)
c++·设计模式·解释器模式
ADRU12 小时前
设计模式-责任链模式
java·设计模式·责任链模式
我是苏苏16 小时前
设计模式01:创建型设计模式之单例、简单工厂的使用情景及其基础Demo
java·开发语言·设计模式
肘击鸣的百k路19 小时前
java设计模式
设计模式
bandaoyu19 小时前
【设计模式】命令模式
设计模式·命令模式
whynogome19 小时前
快速理解24种设计模式
设计模式
码农爱java20 小时前
设计模式--装饰器模式【结构型模式】
java·设计模式·面试·装饰器模式·原理·23 中设计模式
爱学习的白杨树20 小时前
设计模式介绍
设计模式