程序设计中的主要设计模式通常分为三大类,共23种:
1. 创建型模式(Creational Patterns)
-
单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。
-
工厂方法模式(Factory Method):定义创建对象的接口,由子类决定实例化哪个类。
-
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。
-
建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。
-
原型模式(Prototype):通过复制现有对象来创建新对象。
2. 结构型模式(Structural Patterns)
-
适配器模式(Adapter):将一个类的接口转换成客户希望的另一个接口。
-
桥接模式(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。
-
组合模式(Composite):将对象组合成树形结构以表示"部分-整体"的层次结构。
-
装饰器模式(Decorator):动态地给对象添加职责,相比生成子类更为灵活。
-
外观模式(Facade):为子系统中的一组接口提供一个统一的接口。
-
享元模式(Flyweight):通过共享技术有效地支持大量细粒度对象。
-
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
3. 行为型模式(Behavioral Patterns)
-
责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合。
-
命令模式(Command):将请求封装为对象,使你可以用不同的请求对客户进行参数化。
-
解释器模式(Interpreter):给定一个语言,定义其文法的一种表示,并定义一个解释器。
-
迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
-
中介者模式(Mediator):定义一个中介对象来封装一系列对象之间的交互。
-
备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
-
观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。
-
状态模式(State):允许对象在其内部状态改变时改变其行为。
-
策略模式(Strategy):定义一系列算法,将它们封装起来,并使它们可以互相替换。
-
模板方法模式(Template Method):定义一个操作中的算法骨架,将一些步骤延迟到子类中。
-
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
4.策略模式(Strategy)解释
策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互换。策略模式让算法的变化独立于使用它的客户端,从而使得客户端可以在运行时动态地选择算法,而不需要修改客户端代码。
策略模式的核心思想是将算法的实现与使用算法的客户端解耦,通过将算法封装在独立的策略类中,客户端可以根据需要选择不同的策略来执行任务。
策略模式通常涉及以下三个角色:
- Strategy(策略接口):定义所有支持的算法的公共接口。
- ConcreteStrategy(具体策略):实现策略接口的具体算法。
- Context(上下文):持有一个策略对象的引用,并通过策略接口调用具体的算法。
5.C# 策略模式演示代码
csharp
using System;
// Strategy接口:定义所有支持的算法的公共接口
interface IStrategy
{
void Execute();
}
// ConcreteStrategyA类:实现策略接口的具体算法A
class ConcreteStrategyA : IStrategy
{
public void Execute()
{
Console.WriteLine("Executing Strategy A");
}
}
// ConcreteStrategyB类:实现策略接口的具体算法B
class ConcreteStrategyB : IStrategy
{
public void Execute()
{
Console.WriteLine("Executing Strategy B");
}
}
// Context类:持有一个策略对象的引用,并通过策略接口调用具体的算法
class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public void SetStrategy(IStrategy strategy)
{
_strategy = strategy;
}
public void ExecuteStrategy()
{
_strategy.Execute();
}
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
// 创建上下文对象,并设置初始策略
Context context = new Context(new ConcreteStrategyA());
// 执行初始策略
context.ExecuteStrategy();
// 更改策略并执行
context.SetStrategy(new ConcreteStrategyB());
context.ExecuteStrategy();
}
}
6.代码说明
-
IStrategy接口 :这是一个策略接口,定义了所有支持的算法的公共接口。在这个例子中,接口只有一个
Execute
方法。 -
ConcreteStrategyA类和ConcreteStrategyB类 :这两个类实现了
IStrategy
接口,分别提供了具体的算法实现。ConcreteStrategyA
和ConcreteStrategyB
分别实现了Execute
方法,输出不同的执行信息。 -
Context类 :这是上下文类,持有一个
IStrategy
对象的引用。Context
类通过构造函数或SetStrategy
方法设置策略对象,并通过ExecuteStrategy
方法调用策略对象的Execute
方法。 -
客户端代码 :在
Main
方法中,我们创建了一个Context
对象,并设置了初始策略为ConcreteStrategyA
。然后,我们调用ExecuteStrategy
方法执行初始策略。接着,我们更改策略为ConcreteStrategyB
,并再次调用ExecuteStrategy
方法执行新的策略。
7.运行结果
Executing Strategy A
Executing Strategy B
8.总结
策略模式通过将算法封装在独立的策略类中,使得算法的变化独立于使用它的客户端。客户端可以在运行时动态地选择不同的策略来执行任务,而不需要修改客户端代码。这种模式非常适合需要在运行时根据条件选择不同算法的场景。