软件设计模式

一.创建型模式

该类型模式是对对象实例化过程饿抽象,他对采用抽象类所定义的接口,封装了系统中对象如何创建,组合等信息。该模式允许在系统中创建对象,而不需要在代码中标识特定类的类型,这样用户就不需要编写大量,复杂的代码来初始化对象,它是通过该类的子类来创建对象的。但可能会限制在系统内创建对象的类型或数目。


1.抽象工厂 Abstract Factory

旨在提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。它允许客户端代码在不需要了解具体实现的情况下,使用这些对象。帮助开发者管理和维护复杂的对象创建过程。

(Abstract Factory):抽象工厂 - 定义创建产品对象的接口。

(Concrete Factory):具体工厂 - 实现抽象工厂接口,负责创建具体的产品对象。

(Abstract Product):抽象产品 - 定义产品的接口。

(Product):具体产品 - 实现抽象产品接口的具体类。

使用场景:

- 当系统需要独立于其产品的创建、组合和表示时。

- 当系统需要使用多个系列的产品,而不需要依赖于具体的产品实现时。


2.构建器 Builder

旨在简化复杂对象的构建过程。它通过将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

Builder(建造者):定义创建一个产品所需的各个部件的抽象接口。

ConcreteBuilder(具体建造者):实现Builder接口,构建和装配各个部件,提供一个方法来返回构建好的产品。

Director(指挥者):负责管理Builder的构建过程,调用具体建造者的方法来构建产品。

Product(产品):最终构建的复杂对象。

使用场景:

- 当一个对象的构建过程复杂,且需要多个步骤时。

- 构造过程必须允许已构建对象有不同表示。


3. 工厂方法 Factory Method

它提供了一个接口用于创建对象,但由子类决定要实例化的类是哪一个。通过这种方式,工厂方法模式将对象的实例化推迟到子类中进行

产品接口(Product):定义了工厂方法所创建的对象的接口。

具体产品(ConcreteProduct):实现了产品接口的具体类。

工厂接口(Creator):声明了一个工厂方法,返回一个产品对象。

具体工厂(ConcreteCreator):实现了工厂接口,返回具体产品的实例。

使用场景:

- 当一个类无法预见要创建的对象的类时。

- 当一个类希望由其子类来指定所创建的对象时。

- 当一个类委托子类来创建对象时。


4.原型 Prototype

它允许通过复制现有的实例来创建新对象,而不是通过直接实例化类。这种模式特别适合于需要创建大量相似对象的场景,能够提高性能并减少内存消耗。

原型接口(Prototype):定义一个用于复制自身的接口。

具体原型(ConcretePrototype):实现原型接口,提供具体的克隆方法。

客户端(Client):使用原型实例来创建新的对象。

使用场景

- 当一个类的实例化成本较高时,可以考虑使用原型模式。

- 当需要创建大量相似对象时,原型模式可以有效减少内存消耗。

- 当对象的状态需要在运行时动态改变时,原型模式提供了灵活性。


5.单独 Singleton

确保一个类只有一个实例,并提供一个全局访问点。它常用于需要控制资源访问的场景,比如数据库连接、线程池等。

使用场景

- 需要控制资源的访问,如数据库连接、线程池等。

- 需要全局访问的配置类。

- 需要在整个应用中共享的状态。


二.结构型模式

该类模式主要用于如何组合已有的类和对象以获得更大的结构,一般借鉴封装,代理,继承等概念讲一个或多个类或对象进行组合,封装,以提供同一的外部视图或新的功能。

1.适配器模式  Adapter

它允许将一个类的接口转换成客户端所期望的另一种接口。适配器模式使得原本由于接口不兼容而无法一起工作的类可以协同工作。

1. **目标接口(Target)**:客户端所期待的接口。

2. **适配者(Adaptee)**:需要被适配的类,通常是已有的类。

3. **适配器(Adapter)**:实现目标接口,并持有一个适配者的实例,将目标接口的方法调用转发给适配者。

使用场景

- 当你希望使用一些现有的类,但其接口不符合你的需求时。

- 当你想要创建一个可以与多个不兼容接口的类协同工作的系统时。


2.桥接模式  Bridge

它通过将抽象部分与实现部分分离,使得二者可以独立变化。这个模式主要用于解决类的层次结构过于复杂的问题

1. **抽象类(Abstraction)**:定义了抽象的接口,并持有一个指向实现部分的引用。 2. **扩展抽象类(RefinedAbstraction)**:继承自抽象类,扩展了抽象类的功能。 3. **实现类接口(Implementor)**:定义了实现部分的接口。 4. **具体实现类(ConcreteImplementor)**:实现了实现类接口,提供具体的实现。

适用场景 - 当你需要在多个维度上扩展系统时。 - 当你希望避免在类的层次结构中产生过多的子类时。 - 当你希望在运行时动态切换实现时。


3.组合模式  Composite

它允许将对象组合成树形结构以表示“部分-整体”的层次关系。组合模式使得客户端对单个对象和组合对象的使用具有一致性。

1. **组件(Component)**:定义了叶子和组合对象的共同接口。 2. **叶子(Leaf)**:实现了组件接口,表示树的叶子节点。 3. **组合(Composite)**:实现了组件接口,能够包含叶子和其他组合对象。

适用场景 - 当需要表示对象的部分-整体层次结构时。 - 当希望客户端忽略组合对象和单个对象的差异时。


4.装饰者模式  Decorator

它允许在不改变对象自身的情况下,动态地给一个对象添加一些额外的职责或功能。这个模式通过创建一个装饰类来包裹原有的类,从而实现对原有类的功能扩展。尤其是在需要动态添加功能的场景中,如图形界面、流处理等。

组件接口(Component):定义一个对象接口,可以给这些对象动态地添加职责。

具体组件(ConcreteComponent):实现了组件接口的具体对象,定义了被装饰的对象。

装饰器(Decorator):持有一个组件对象的引用,并定义与组件接口一致的接口。

具体装饰器(ConcreteDecorator):扩展了装饰器类,添加了额外的职责。

工作原理

- 通过将具体组件对象传递给装饰器,装饰器可以在调用具体组件的方法之前或之后添加额外的功能。

- 可以通过多个装饰器来组合功能,形成一个灵活的功能扩展机制。


5.外观模式  Facade

它为复杂的子系统提供一个统一的接口,使得子系统更易于使用。通过外观模式,客户端可以通过一个简单的接口与复杂的系统进行交互,而不需要了解系统内部的复杂性。

外观类(Facade):提供一个简单的接口,封装了复杂的子系统。

子系统类(Subsystem):实现具体的功能,通常包含多个类,外观类通过这些类来完成具体的操作。

使用场景

- 当需要为复杂的子系统提供一个简单的接口时。

- 当需要解耦客户端与子系统之间的关系时。

- 当希望提高系统的可读性和可维护性时。


6.享元模式  Flyweight

旨在通过共享对象来减少内存使用和提高性能。它特别适用于大量相似对象的场景。享元模式的核心思想是将对象的状态分为两部分:内部状态和外部状态。内部状态**:对象可以共享的状态,通常是不可变的。多个对象可以共享同一个内部状态。 **外部状态**:对象特有的状态,通常是可变的。外部状态在使用对象时传递给对象。

Flyweight:享元接口,定义了需要实现的方法。

ConcreteFlyweight:具体享元类,实现了Flyweight接口,包含内部状态。

FlyweightFactory:享元工厂,负责创建和管理享元对象,确保共享相同的对象。

使用场景

当应用程序需要大量相似对象时。

当对象的创建和管理成本较高时。

当需要减少内存使用时。


7.代理模式  Proxy

它为其他对象提供一种代理以控制对这个对象的访问。

主题接口(Subject):定义了代理和真实对象的共同接口。

真实主题(RealSubject)**:实现了主题接口,定义了代理所代表的真实对象。

代理(Proxy:持有对真实主题的引用,并实现了主题接口,控制对真实主题的访问。

代理模式通常用于以下几种情况:

1. **远程代理**:为一个对象在不同地址空间提供局部代表。

2. **虚拟代理**:根据需要创建开销较大的对象,延迟对象的创建。

3. **保护代理**:控制对原始对象的访问,提供不同的访问权限。

使用场景

- **网络请求**:在网络请求中,代理可以用于缓存响应,减少网络延迟。

- **权限控制**:在访问敏感数据时,代理可以检查用户权限。

- **资源管理**:在处理大对象时,代理可以延迟加载,优化性能。


三.行为型模式 Behavioral Patterns

该类模式主要用于对象之间的职责及其提供的服务的分配,它不仅描述对象或类的模式,还描述了他们之间的通信模式,特别是描述一组对等的对象怎样相互协作以完成其中任一对象都无法单独完成的任务。

1.责任链模式 Chain of Responsibility 

它允许将请求的发送者和接收者解耦。通过将多个处理对象连接成一条链,发送者可以将请求沿着这条链传递,直到有一个对象处理它为止。适用于需要多个处理者处理请求的场景。通过将处理者组织成链,可以灵活地管理请求的处理过程。

1. **Handler(处理者)**: 定义一个处理请求的接口,并实现链中的处理逻辑。

2. **ConcreteHandler(具体处理者)**: 实现Handler接口,处理请求或将请求传递给下一个处理者。

3. **Client(客户端)**: 创建具体处理者并设置链的顺序,发送请求。

工作原理

1. 客户端创建多个处理者,并将它们连接成一条链。

2. 客户端发送请求,链中的处理者依次检查是否能够处理该请求。

3. 如果某个处理者能够处理请求,则执行相应的处理逻辑;如果不能,则将请求传递给链中的下一个处理者。


2.命令模式 Command 

它将请求封装为对象,从而使你能够使用不同的请求、队列或日志请求,以及支持可撤销的操作。

1. **命令接口(Command)**:定义一个执行操作的接口。

2. **具体命令(ConcreteCommand)**:实现命令接口,定义与接收者之间的绑定关系,并调用接收者的相应操作。

3. **接收者(Receiver)**:知道如何实施与执行一个请求相关的操作。

4. **调用者(Invoker)**:负责调用命令对象来执行请求。

5. **客户端(Client)**:创建具体命令对象并设置接收者。

使用场景

- 当你需要将请求参数化并传递给其他对象时。

- 当你需要支持撤销和重做操作时。

- 当你需要将请求排队或记录请求日志时。

- 当你需要实现宏命令(多个命令的组合)时。


3.解释器模式  Interpreter

主要用于定义一种语言的文法,并通过解释器来解释该语言中的句子。这个模式通常用于需要解析和执行特定语言或表达式的场景,比如编程语言的解析器、脚本语言的执行等。

1. **抽象表达式(AbstractExpression)**:定义一个解释操作的接口,所有具体表达式都需要实现这个接口。

2. **终结符表达式(TerminalExpression)**:实现了抽象表达式接口,表示文法中的基本元素。通常是一些简单的语法规则。

3. **非终结符表达式(NonTerminalExpression)**:同样实现了抽象表达式接口,表示文法中的复杂结构,由多个终结符和非终结符组合而成。

4. **上下文(Context)**:包含了在解释过程中需要的一些信息,通常是输入的字符串或其他数据。

工作原理

解释器模式的核心思想是将一个复杂的表达式分解为多个简单的表达式,然后通过递归的方式来解释这些表达式。

具体步骤如下:

1. **定义文法**:首先需要定义要解析的语言的文法规则。

2. **构建表达式树**:根据文法规则构建一个表达式树,树的每个节点都是一个表达式。

3. **解释表达式**:通过遍历表达式树,调用每个节点的解释方法,最终得到结果。

使用场景

- 需要解析和执行简单的语言或表达式。

- 需要对复杂的文法进行处理。

- 需要在运行时动态地解释和执行代码。


4.迭代器模式 Iterator

它的主要目的是提供一种方法来顺序访问一个集合对象中的元素,而不暴露该对象的内部表示。尤其在需要遍历复杂数据结构时。它使得代码更加清晰和易于维护,同时也提高了代码的复用性。

1. **迭代器(Iterator)**:定义了访问和遍历元素的接口。

2. **具体迭代器(Concrete Iterator)**:实现了迭代器接口,负责遍历具体集合的元素。

3. **聚合(Aggregate)**:定义了创建迭代器的接口。

4. **具体聚合(Concrete Aggregate)**:实现了聚合接口,返回一个具体的迭代器。


5.中介者模式  Mediator

它通过引入一个中介者对象来减少对象之间的直接交互,从而降低系统的复杂性。中介者负责协调多个对象之间的交互,促进它们之间的通信,而不需要它们直接引用彼此。

1. **中介者接口(Mediator)**:定义了与各个同事对象交互的方法。

2. **具体中介者(ConcreteMediator)**:实现中介者接口,维护对各个同事对象的引用,并协调它们之间的交互。

3. **同事类(Colleague)**:各个参与者,它们通过中介者进行交互,而不是直接相互交互。


6.备忘录模式  Memento

用于在不暴露对象内部状态的情况下,保存和恢复对象的状态。这个模式特别适用于需要实现撤销操作的场景,比如文本编辑器、游戏等。提供了一种简单而有效的方式来保存和恢复对象的状态,而不需要暴露对象的内部实现细节。这使得它在需要状态管理的应用程序中非常有用。

1. **Originator(发起人)**:需要保存其内部状态的对象。它可以创建一个备忘录来记录当前状态,并可以使用备忘录恢复状态。

2. **Memento(备忘录)**:用于存储发起人的内部状态。备忘录通常是一个不可变的对象,外部对象无法直接访问其内部状态。

3. **Caretaker(看护者)**:负责管理备忘录的对象。看护者可以保存和恢复备忘录,但不能修改备忘录的内容。

使用场景 - 文本编辑器的撤销/重做功能。 - 游戏中的状态保存与加载。 - 任何需要保存和恢复对象状态的场景。


7.观察者模式 Observer 

用于建立一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都能够自动收到通知并更新。这种模式常用于实现事件处理系统或消息传递系统。例如事件处理、数据绑定、MVC架构等。

1. **主题(Subject)**:被观察的对象,维护观察者的列表,并提供注册、注销观察者的方法。

2. **观察者(Observer)**:依赖于主题的对象,当主题状态变化时,观察者会收到通知并进行相应的更新。

3. **具体主题(Concrete Subject)**:实现了主题接口的具体类,包含状态变化的逻辑。

4. **具体观察者(Concrete Observer)**:实现了观察者接口的具体类,定义了在接收到通知时的行为。

工作流程

1. 观察者注册到主题。

2. 主题状态发生变化。

3. 主题通知所有注册的观察者。

4. 观察者根据通知更新自身状态。


8.状态模式  State

它允许一个对象在其内部状态改变时改变其行为。换句话说,状态模式可以让一个对象在其状态改变时表现得像是改变了其类。

1. **Context(上下文)**:持有一个状态对象的引用,并且可以在运行时改变它的状态。

2. **State(状态接口)**:定义一个接口,用于封装与特定状态相关的行为。

3. **ConcreteState(具体状态)**:实现状态接口的具体状态类,每个具体状态类都实现了与该状态相关的行为。

工作原理

- 上下文对象持有一个状态对象的引用。

- 当上下文的状态改变时,它会将状态对象替换为另一个状态对象。

- 每个状态对象实现了状态接口中的方法,定义了在该状态下的具体行为。


9.策略模式  Strategy

它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式让算法独立于使用它的客户端而变化。

1. **策略接口(Strategy)**:定义一个公共接口,所有具体策略都需要实现这个接口。

2. **具体策略(ConcreteStrategy)**:实现策略接口的具体算法。

3. **上下文(Context)**:持有一个策略的引用,并可以在运行时选择具体的策略。

使用场景

- 当你有多个算法可以选择,并且希望在运行时选择其中一个。

- 当你希望将算法的实现与使用算法的代码分离。

- 当你需要避免使用大量的条件语句(如 `if-else` 或 `switch`)。


10.访问者模式  Visitor

它允许你在不改变对象结构的前提下,定义新的操作。这个模式的核心思想是将操作与对象结构分离,使得你可以在不修改对象的情况下,添加新的操作。适用于需要对一组对象执行多种操作的场景。

1. **Visitor(访问者)**: 定义了对每个元素的访问操作。

2. **Element(元素)**: 接受访问者的访问,通常是一个接口或抽象类。

3. **ConcreteElement(具体元素)**: 实现了 Element 接口的具体类。

4. **ObjectStructure(对象结构)**: 维护一组元素,并提供一个方法来允许访问者访问这些元素。

工作原理

- 访问者模式通过在元素类中定义一个 `accept` 方法,接受一个访问者对象。

- 访问者对象实现了对每个具体元素的操作。

- 当访问者访问元素时,元素会调用访问者的相应方法,从而实现对元素的操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值