设计模式学习

目前我的编程主要是面向过程,能够获得非常高的效率,我也能很好得将其功能模块化,变得易于理解和维护。诚然很大程度的原因是因为我面对的需求可以被抽象为一个完整的模块或者我只需在非常成熟的软件增加功能,需求是简单且稳定的,一个人可以独立完成,需要维护的数据结构也不多。复杂的软件工程中往往会面向对象,因为要具备比较高的可维护性、可扩展性和代码维护性,封装、继承、多态是OOP的基础,设计模式是广泛接受的、经过实践验证的软件设计方法。有5+1大设计原则,缩写为 SOLID
不知道有没有把所有设计模式都用一遍,且没有过度设计,粒度合适的,但是其实你不懂他的需求,可能也不知道他为什么要这么抽象,但是你只是看看我的总结可能还不如问chatgpt

一、单一职责原则(Single Responsibility Principle,SRP)

每个类应该只负责一个特定的功能或职责。
一个类应该只有一个引起它变化的原因。将不同职责的代码隔离到不同的类中,可以提高代码的可维护性和可理解性。

二、开放封闭原则(Open-Closed Principle,OCP)

软件实体(类、模块、函数等)应该是可扩展的,但不可修改的。
在添加新功能时,不应该修改现有的代码,而是通过扩展已有的代码来实现。
增加需求时,扩展新代码,而非修改已有代码

三、里式替换原则(Liskov Substitution Principle,LSP)

子类应该能够替代父类,而不影响程序的正确性。
子类应该继承父类的行为,但不能改变其预期的行为。

四、接口隔离原则(Interface Segregation Principle,ISP)

不应该强迫客户端依赖于其不需要的接口。
一个类不应该实现它不需要的接口,而应该将接口分解为更小的、更专注的部分。

五、依赖倒置原则(Dependency Inversion Principle,DIP)

高层模块不应该依赖于低层模块,两者都应该依赖于抽象。
面向接口编程,抽象不应该依赖于具体实现细节,而是具体实现应该依赖于抽象。

六、迪米特法则(Law of Demeter),最少知识原则(Principle of Least Knowledge)

一个模块(类)不应该了解太多关于其他模块的内部细节。
一个类应该只与其直接的朋友通信,而不应该直接与陌生的类交互。

七、23种设计模式

基于5大设计原则,产生了23种设计模式

1.单例模式(Singleton Pattern)

旨在确保一个类只有一个实例,并提供全局访问点以获取该实例。
这种模式适用于需要在整个应用程序中共享一些资源或状态的情况,例如配置信息、数据库连接池、线程池等

2.工厂方法模式(Factory Method Pattern)

提供了一种创建对象的接口,但将具体的实例化过程延迟到子类中进行。
这种模式通过将对象的实例化与使用代码分离,使得代码更具灵活性,能够根据需要动态创建不同类型的对象。

3.抽象工厂模式(Abstract Factory Pattern)

它提供了一种接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
可以看作是多个工厂方法模式的结合,它用于创建一组相关的产品对象。

4.模板方法模式(Template Method Pattern)

定义了一个算法的骨架,但允许子类在不改变算法结构的情况下重新定义其中的某些步骤。
通过将共同的算法步骤放在父类中,而将特定步骤的实现延迟到子类中,使得代码的复用性和灵活性都得到提高。

5.建造者模式(Builder Pattern)

允许你将一个复杂对象的构建过程与其表示分离,从而可以使用相同的构建过程来创建不同的表示。
适用于需要创建复杂对象,且对象的构建过程相对稳定,但表示可以有多种变化的情况。

6.代理模式(Proxy Pattern)

允许你提供一个代理对象,用于控制对其它对象的访问。
在访问对象时引入了一个中间层,使得可以添加额外的功能,如延迟加载、权限控制、缓存等,而不需要修改原始对象的代码。

7.原型模式(Prototype Pattern)

允许你通过复制(克隆)一个现有对象来创建新对象,而无需从头开始编写代码。
适用于那些创建过程复杂、初始化消耗大量资源的对象,通过克隆可以提高创建效率。

8.中介者模式(Mediator Pattern)

降低多个对象之间的耦合性,通过引入一个中介者对象来协调对象之间的交互。
将对象之间的交互行为集中在一个中介者对象中,而不是让对象直接相互通信。

9.命令模式(Command Pattern)

将命令的请求者(Client)和命令的执行者(Receiver)解耦,通过一个具体的命令类来封装请求,将请求的参数和方法调用封装成一个命令对象。
将一个请求封装成一个对象,从而使得可以将请求参数化和延迟执行,实现将发出请求的对象与执行请求的对象解耦。

10. 责任链模式(Chain of Responsibility Pattern)

将多个处理对象(处理器)连接成一个链,从而使得请求在这个链上传递,直到有一个处理器能够处理该请求或者请求到达链的末尾。
将请求的发送者和接收者解耦,使得多个对象都有机会处理请求,而不需要显式指定接收者。

11.装饰器模式(Decorator Pattern)

允许动态地将行为添加到对象中,而无需使用子类来扩展对象的功能。
装饰器模式通过创建一系列装饰器类来包装原始对象,每个装饰器类都添加一些额外的功能。

12.策略模式(Strategy Pattern)

定义了一系列算法或策略,并将其封装成独立的对象,使得这些算法可以相互替换,而不影响使用算法的客户端。
将算法的实现与使用算法的客户端分离,使得算法可以独立变化,而客户端不需要知道具体的算法实现细节。

13.适配器模式(Adapter Pattern)

允许将不兼容的接口转换为客户端所期望的接口,从而使不同接口的类能够协同工作。
通过创建一个适配器类,将一个类的接口转换为客户端所期望的接口。

14.迭代器模式(Iterator Pattern)

提供一种统一的方式来访问集合(或容器)中的元素,而不暴露底层集合的实现细节。
将遍历集合的操作从集合中分离出来,由一个单独的迭代器对象来负责遍历集合中的元素。

15.组合模式(Composite Pattern)

将对象组合成树状结构来表示“部分-整体”的关系。
将对象分为两类:叶子对象(Leaf)和容器对象(Composite)。叶子对象表示树的最终节点,容器对象表示可以包含其他子对象的节点。这样就形成了一个递归的结构,可以通过一致的方式处理整体和部分。

16.观察者模式(Observer Pattern)

一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。
将观察者(订阅者)和被观察者(发布者)解耦,使得它们可以独立变化而互不影响。被观察者维护一个观察者列表,当其状态发生变化时,会通知所有观察者进行更新。

17.外观模式(Facade Pattern)

提供了一个统一的接口,用来访问子系统中的一组接口,从而简化客户端与子系统之间的交互。
将客户端与子系统之间的交互由复杂的直接交互转换为通过外观接口的间接交互。这样可以降低客户端的复杂性,同时隔离客户端与子系统之间的耦合。

18.备忘录模式(Memento Pattern)

允许在不破坏封装的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要时进行恢复。
将对象的状态保存到一个备忘录对象中,这个备忘录对象可以被存储、传递或恢复。这样,对象的状态变化不会影响外部,同时可以在需要的时候还原到之前的状态。

19.访问者模式(Visitor Pattern)

用于将数据结构与数据操作分离开来。访问者模式允许在不修改数据结构的情况下,定义新的操作,从而实现对数据结构的不同操作。
将数据结构与操作进行解耦,通过在数据结构中定义一个接受访问者的方法,使得数据结构可以接受不同类型的访问者来执行操作。这样,可以在不改变数据结构的情况下,根据不同的需求定义不同的访问者。

20.状态模式(State Pattern)

允许一个对象在其内部状态改变时改变其行为。状态模式将对象的状态封装成不同的状态类,从而实现状态之间的切换,使得对象在不同状态下可以有不同的行为。
将对象的行为和状态进行分离,使得对象的状态可以独立变化,而不影响对象的行为。通过定义不同的状态类和状态之间的切换条件,可以实现对象的动态行为变化。

21.解释器模式(Interpreter Pattern)

定义了一种语言文法的表示,并且提供了一个解释器来解释这种语言的句子。解释器模式用于解决特定领域中的问题,其中问题可以表示为一种语言,而解释器可以用来解释这种语言的表达式。
解释器模式的核心思想是将语言的文法规则表示为类的层次结构,每个类代表一个文法规则,同时提供解释方法。这样,可以通过组合这些类来构建复杂的语法规则,并使用解释器来解释文法的句子。

22.享元模式(Flyweight Pattern)

通过共享对象来减少内存使用和提高性能。享元模式适用于存在大量相似对象的情况,通过共享这些相似对象的内部状态,可以有效减少内存消耗。
象的状态分为内部状态和外部状态。内部状态是可以共享的,不随对象的上下文变化而变化,而外部状态是不可共享的,会随着对象的上下文而变化。通过共享相同的内部状态,多个对象可以共享一份数据,从而节省内存。

23.桥接模式(Bridge Pattern)

将抽象部分与其实现部分分离,使它们可以独立变化。桥接模式通过将两个维度的变化分离开来,使得系统更加灵活,同时避免了类爆炸问题。
将抽象类和实现类通过桥接接口连接在一起,使得它们可以独立变化。抽象类和实现类可以在运行时进行组合,从而得到不同的组合效果。这样,可以通过新增抽象类和实现类来扩展系统,而不需要修改现有代码。

posted @ 2023-08-15 17:40  暴力都不会的蒟蒻  阅读(12)  评论(0编辑  收藏  举报