一,前言
当今软件开发领域发展迅速,软件系统变得越来越复杂。在这个过程中,面对不断变化的需求和业务场景,如何快速而又高效地完成软件开发,成为了一个重要的问题。设计模式作为一种被广泛使用的解决方案,代表着最佳的实践。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的,通常被有经验的面向对象的软件开发人员所采用。
设计模式是一套被反复使用的、多数人知晓的、经过分类汇总的代码设计经验总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
二、什么是设计模式
定义设计模式
设计模式是在软件开发中,经过多年的实践和总结出来的一种解决特定问题的经验性方法。它是一种可重用的解决方案,可以帮助开发人员避免在设计软件时遇到的常见问题,提高软件的质量和可维护性。
GOF四人帮
在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。
四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出的设计模式主要是基于以下的面向对象设计原则。
- 对接口编程而不是对实现编程。
- 优先使用对象组合而不是继承。
设计模式的目标
设计模式的目标主要包括以下几点:
- 降低耦合性:通过使用设计模式,可以将系统中的各个模块解耦,提高系统的可维护性和可扩展性。
- 提高重用性:设计模式提供了一些通用的解决方案,能够帮助我们避免重复造轮子,提高代码的重用性。
- 提高代码可读性:设计模式提供了一种通用的语言和结构,使得代码更加易于理解和阅读。
- 代码维护性:因为各模块解耦,使得代码更容易维护。
- 错误减少:使用设计模式可以降低代码的错误率,因为这些模式是经过验证的最佳实践,有助于避免一些常见的错误。
- 高效性:设计模式已经被广泛认可,因此它们已经经过优化和优化,可以提高代码的效率和性能。
三、设计模式六大原则
设计模式有着严格的原则指导,这些原则可以帮助开发人员构建高质量、易于维护和可重用的软件系统。下面介绍六大设计原则
1、单一职责原则(SRP)
单一职责原则指的是一个类只负责一个功能领域中的相应职责,或者可以简单地说一个类只做一件事情。如果一个类负责的功能过于复杂,应该将其拆分为多个类,每个类只负责一个功能领域中的相应职责,以便实现代码的复用和维护。
2、开闭原则(OCP)
开闭原则指的是一个软件实体应该对扩展开放,对修改关闭。也就是说,在设计一个系统时,应该尽量避免对原有的代码进行修改,而是通过扩展的方式来实现新的功能。
3、里氏替换原则(LSP)
里氏替换原则是面向对象设计的基本原则之一。 里氏替换原则是指,任何基类可以出现的地方,子类一定可以出现。就是说子类可以替换父类出现在程序中的任何地方,并且保证程序的逻辑行为不变。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
4、依赖倒置原则(DIP)
这个原则是开闭原则的基础,依赖倒置原则指的是高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象接口不应该依赖具体实现,具体实现应该依赖抽象接口。简单说就是针对接口编程,程序直接调用接口,而不调用实现类,这样就降低了客户端与实现模块间的耦合。
5、接口隔离原则(ISP)
接口隔离原则是指对接口中不同种类用途的方法进行拆分隔离,使客户端不用去实现它不需要的方法。换言之一个类对另一个类的依赖应该建立在最小的接口上,应该尽量将接口拆分为更小的和更具体的接口,使接口中只包含客户端所需要的方法。
6、迪米特法则(LoD)
一个对象应当尽量少地与其他对象之间发生交互,尽可能降低类之间的耦合。又称最少知识原则,最少知识是指一个对象对于其他对象知道得越少越好。
四、设计模式的分类
设计模式可以分为三种类型:创建型模式、结构型模式和行为型模式。
创建型模式
这类模式提供创建对象的机制, 能够提升已有代码的灵活性和可复⽤性。
序号 | 类型 | 描述 |
---|---|---|
1 | 工厂方法模式(Factory Method Pattern) | 定义⼀个创建对象的接⼝,让其⼦类⾃⼰决定实例化哪⼀个⼯⼚类,⼯⼚模式 使其创建过程延迟到⼦类进⾏。 |
2 | 抽象工厂模式(Abstract Factory Pattern) | 提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。 |
3 | 单例模式(Singleton Pattern) | 保证⼀个类仅有⼀个实例,并提供⼀个 访问它的全局访问点。 |
4 | 建造者模式(Builder Pattern) | 将⼀个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 |
5 | 原型模式(Prototype Pattern) | ⽤原型实例指定创建对象的种类,并且通过拷⻉这些原型创建新的对象。 |
结构型模式
这类模式介绍如何将对象和类组装成较⼤的结构, 并同时保持结构的灵活和⾼效。
序号 | 类型 | 描述 |
---|---|---|
1 | 适配器模式(Adapter Pattern) | 将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以 ⼀起⼯作。 |
2 | 桥接模式(Bridge Pattern) | 将抽象部分与实现部分分离,使它们都 可以独⽴的变化。 |
3 | 组合模式(Composite Pattern) | 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得⽤户对单个对象和组合对象的使⽤具有⼀致性。 |
4 | 装饰器模式(Decorator Pattern) | 动态地给⼀个对象添加⼀些额外的职 责。就增加功能来说,装饰器模式相⽐ ⽣成⼦类更为灵活。 |
5 | 外观模式(Facade Pattern) | 为⼦系统中的⼀组接⼝提供⼀个⼀致的 界⾯,外观模式定义了⼀个⾼层接⼝, 这个接⼝使得这⼀⼦系统更加容易使 ⽤。 |
6 | 享元模式(Flyweight Pattern) | 运⽤共享技术有效地⽀持⼤量细粒度的对象。 |
7 | 代理模式(Proxy Pattern) | 为其他对象提供⼀种代理以控制对这个对象的访问。 |
行为型模式
这类模式负责对象间的⾼效沟通和职责委派。
序号 | 类型 | 描述 |
---|---|---|
1 | 责任链模式(Chain of Responsibility Pattern) | 避免请求发送者与接收者耦合在⼀起,让多 个对象都有可能接收请求,将这些对象连接 成⼀条链,并且沿着这条链传递请求,直到 有对象处理它为⽌。 |
2 | 命令模式(Command Pattern) | 将⼀个请求封装成⼀个对象,从⽽使您可以⽤不同的请求对客户进⾏参数化。 |
3 | 迭代器模式(Iterator Pattern) | 提供⼀种⽅法顺序访问⼀个聚合对象中各个 元素, ⽽⼜⽆须暴露该对象的内部表示。 |
4 | 中介者模式(Mediator Pattern) | ⽤⼀个中介对象来封装⼀系列的对象交互, 中介者使各对象不需要显式地相互引⽤,从⽽使其耦合松散,⽽且可以独⽴地改变它们 之间的交互。 |
5 | 备忘录模式(Memento Pattern) | 在不破坏封装性的前提下,捕获⼀个对象的 内部状态,并在该对象之外保存这个状态。 |
6 | 观察者模式(Observer Pattern) | 定义对象间的⼀种⼀对多的依赖关系,当⼀ 个对象的状态发⽣改变时,所有依赖于它的 对象都得到通知并被⾃动更新。 |
7 | 状态模式(State Pattern) | 允许对象在内部状态发⽣改变时改变它的⾏ 为,对象看起来好像修改了它的类。 |
8 | 策略模式(Strategy Pattern) | 定义⼀系列的算法,把它们⼀个个封装起来, 并且使它们可相互替换。 |
9 | 模板方法模式(Template Method Pattern) | 定义⼀个操作中的算法的⻣架,⽽将⼀些步 骤延迟到⼦类中。模板⽅法使得⼦类可以不 改变⼀个算法的结构即可᯿定义该算法的某 些特定步骤。 |
10 | 访问者模式(Visitor Pattern) | 主要将数据结构与数据操作分离,以便不改变对象结构的情况下增加新的操作。 |
11 | 解释器模式(Interpreter Pattern) | 定义了一种语言的文法,并且建立一个解释器来解释该语言中的句子。适用面较窄。 |
五、结语
创作不易,如果本文对你有帮助,欢迎点赞、收藏加关注,你的支持和鼓励,是我创作的最大动力。