C#常见的设计模式-行为型模式

前言

行为型模式是面向对象设计中的一类设计模式,它关注对象之间的通信和相互作用,以实现特定的行为或功能。在C#中,有许多常见的行为型模式,下面将对其中10种行为型模式进行介绍,并给出相应的代码示例。
C#常见的设计模式-行为型模式_第1张图片


目录

    • 前言
    • 1. 命令模式(Command)
      • 示例代码
      • 解释
    • 2. 解释器模式(Interpreter)
      • 示例代码
      • 解释
    • 3. 迭代器模式(Iterator)
      • 示例代码
      • 解释
    • 4. 中介者模式(Mediator)
      • 示例代码
      • 解释
    • 5. 备忘录模式(Memento)
      • 示例代码
      • 解释
    • 6. 观察者模式(Observer)
      • 示例代码
      • 解释
    • 7. 状态模式(State)
      • 示例代码
      • 解释
    • 8. 策略模式(Strategy)
      • 示例代码
      • 解释
    • 9. 模板方法模式(Template Method)
      • 示例代码
      • 解释
    • 10. 访问者模式(Visitor)
      • 示例代码
      • 解释


1. 命令模式(Command)

命令模式将请求封装成一个对象,从而使得请求发送者和接收者解耦。

示例代码

// 命令接口
public interface ICommand
{
    void Execute();
}

// 具体命令类
public class ConcreteCommand : ICommand
{
    private Receiver _receiver;

    public ConcreteCommand(Receiver receiver)
    {
        _receiver = receiver;
    }

    public void Execute()
    {
        _receiver.Action();
    }
}

// 接收者类
public class Receiver
{
    public void Action()
    {
        Console.WriteLine("执行命令");
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        Receiver receiver = new Receiver();
        ICommand command = new ConcreteCommand(receiver);

        // 客户端只需调用命令的执行方法即可
        command.Execute();
    }
}

解释

在上面的示例中,ICommand接口定义了命令的统一执行方法Execute()ConcreteCommand是具体的命令类,通过调用ReceiverAction()方法来实现对请求的处理。客户端通过实例化具体的命令对象,并调用其执行方法来发出请求。

2. 解释器模式(Interpreter)

解释器模式定义了一种语言文法的表示,并定义了一个解释器来解释语言中的句子。

示例代码

// 抽象表达式类
public abstract class AbstractExpression
{
    public abstract void Interpret(Context context);
}

// 终结符表达式类
public class TerminalExpression : AbstractExpression
{
    public override void Interpret(Context context)
    {
        Console.WriteLine("解释终结符表达式");
    }
}

// 非终结符表达式类
public class NonterminalExpression : AbstractExpression
{
    public override void Interpret(Context context)
    {
        Console.WriteLine("解释非终结符表达式");
    }
}

// 上下文类
public class Context
{
    public string Input { get; set; }
    public string Output { get; set; }
}

// 客户端类
public class Client
{
    public void Main()
    {
        Context context = new Context();
        List<AbstractExpression> expressions = new List<AbstractExpression>();
        
        expressions.Add(new TerminalExpression());
        expressions.Add(new NonterminalExpression());

        foreach (AbstractExpression expression in expressions)
        {
            expression.Interpret(context);
        }
    }
}

解释

在上面的示例中,AbstractExpression是抽象表达式类,由TerminalExpressionNonterminalExpression继承,并分别实现了解释终结符和非终结符表达式的方法。Context类存储解释器的上下文信息。客户端通过实例化具体的解释器对象,并调用其解释方法来实现对句子的解释。

3. 迭代器模式(Iterator)

迭代器模式提供一种顺序访问集合对象元素的方法,而不需要暴露集合对象的内部结构。

示例代码

// 迭代器接口
public interface IIterator<T>
{
    bool HasNext();
    T Next();
}

// 集合接口
public interface ICollection<T>
{
    IIterator<T> CreateIterator();
}

// 具体集合类
public class ConcreteCollection<T> : ICollection<T>
{
    private List<T> _items = new List<T>();

    public void Add(T item)
    {
        _items.Add(item);
    }

    public IIterator<T> CreateIterator()
    {
        return new ConcreteIterator<T>(this);
    }

    public T GetItem(int index)
    {
        return _items[index];
    }

    public int Count
    {
        get { return _items.Count; }
    }
}

// 具体迭代器类
public class ConcreteIterator<T> : IIterator<T>
{
    private ICollection<T> _collection;
    private int _position = 0;

    public ConcreteIterator(ICollection<T> collection)
    {
        _collection = collection;
    }

    public bool HasNext()
    {
        return _position < _collection.Count;
    }

    public T Next()
    {
        T item = _collection.GetItem(_position);
        _position++;
        return item;
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        ICollection<string> collection = new ConcreteCollection<string>();
        collection.Add("Item 1");
        collection.Add("Item 2");
        collection.Add("Item 3");

        IIterator<string> iterator = collection.CreateIterator();
        while (iterator.HasNext())
        {
            string item = iterator.Next();
            Console.WriteLine(item);
        }
    }
}

解释

在上面的示例中,IIterator定义了迭代器接口,ICollection定义了集合接口,并包含一个创建迭代器的方法CreateIterator()ConcreteCollection是具体的集合类,实现了集合接口,并在CreateIterator()方法中返回具体的迭代器对象ConcreteIterator。客户端通过调用集合的CreateIterator()方法来获取迭代器,并可以通过迭代器的HasNext()Next()方法依次访问集合中的元素。

4. 中介者模式(Mediator)

中介者模式定义了一个中介对象来封装一组对象之间的交互,使得这些对象之间不需要直接相互通信。

示例代码

// 中介者接口
public interface IMediator
{
    void SendMessage(string message, Colleague colleague);
}

// 同事类
public abstract class Colleague
{
    protected IMediator _mediator;

    public Colleague(IMediator mediator)
    {
        _mediator = mediator;
    }

    public abstract void ReceiveMessage(string message);
    public abstract void SendMessage(string message);
}

// 具体同事类
public class ConcreteColleagueA : Colleague
{
    public ConcreteColleagueA(IMediator mediator) : base(mediator) { }

    public override void ReceiveMessage(string message)
    {
        Console.WriteLine("Colleague A received: " + message);
    }

    public override void SendMessage(string message)
    {
        _mediator.SendMessage(message, this);
    }
}

public class ConcreteColleagueB : Colleague
{
    public ConcreteColleagueB(IMediator mediator) : base(mediator) { }

    public override void ReceiveMessage(string message)
    {
        Console.WriteLine("Colleague B received: " + message);
    }

    public override void SendMessage(string message)
    {
        _mediator.SendMessage(message, this);
    }
}

// 具体中介者类
public class ConcreteMediator : IMediator
{
    private ConcreteColleagueA _colleagueA;
    private ConcreteColleagueB _colleagueB;

    public void SetColleagueA(ConcreteColleagueA colleagueA)
    {
        _colleagueA = colleagueA;
    }

    public void SetColleagueB(ConcreteColleagueB colleagueB)
    {
        _colleagueB = colleagueB;
    }

    public void SendMessage(string message, Colleague colleague)
    {
        if (colleague == _colleagueA)
        {
            _colleagueB.ReceiveMessage(message);
        }
        else if (colleague == _colleagueB)
        {
            _colleagueA.ReceiveMessage(message);
        }
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        ConcreteMediator mediator = new ConcreteMediator();

        ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
        ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);

        mediator.SetColleagueA(colleagueA);
        mediator.SetColleagueB(colleagueB);

        colleagueA.SendMessage("Hello from Colleague A!");
        colleagueB.SendMessage("Hi from Colleague B!");
    }
}

解释

在上述示例中,IMediator是中介者接口,定义了发送消息的方法SendMessage()Colleague是同事类,每个同事类都持有一个对中介者的引用。ConcreteColleagueAConcreteColleagueB是具体的同事类,实现了同事接口,并在自己的消息发送方法中调用中介者的SendMessage()方法。ConcreteMediator是具体的中介者类,负责将消息转发给其他同事。客户端首先创建中介者对象和同事对象,然后通过设置同事的引用到中介者上,实现同事之间的消息交互。

5. 备忘录模式(Memento)

备忘录模式用于保存和恢复对象的状态,并在不破坏封装性的前提下将对象状态的保存和恢复功能委托给其他对象。

示例代码

// 备忘录类
public class Memento
{
    public string State { get; private set; }

    public Memento(string state)
    {
        State = state;
    }
}

// 发起人类
public class Originator
{
    public string State { get; set; }

    public Memento CreateMemento()
    {
        return new Memento(State);
    }

    public void SetMemento(Memento memento)
    {
        State = memento.State;
    }
}

// 管理者类
public class Caretaker
{
    private Memento _memento;

    public void SaveMemento(Memento memento)
    {
        _memento = memento;
    }

    public Memento RetrieveMemento()
    {
        return _memento;
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.State = "State 1";
        caretaker.SaveMemento(originator.CreateMemento());

        originator.State = "State 2";
        caretaker.SaveMemento(originator.CreateMemento());

        originator.State = "State 3";
        caretaker.SaveMemento(originator.CreateMemento());

        Memento memento = caretaker.RetrieveMemento();
        originator.SetMemento(memento);

        Console.WriteLine(originator.State);  // 输出:State 3
    }
}

解释

在上述示例中,Memento类是备忘录类,用于存储对象的状态;Originator类是发起人类,负责创建备忘录并根据备忘录恢复对象的状态;Caretaker类是管理者类,负责保存和获取备忘录。客户端通过创建发起人、管理者和备忘录对象,并依次设定发起人的状态并将备忘录保存到管理者中,最后可以通过管理者获取备忘录对象并将状态恢复到该备忘录所代表的状态。

6. 观察者模式(Observer)

观察者模式定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其依赖对象都会收到通知并自动更新。

示例代码

// 主题接口
public interface ISubject
{
    void Attach(IObserver observer);
    void Detach(IObserver observer);
    void Notify();
}

// 具体主题类
public class ConcreteSubject : ISubject
{
    private List<IObserver> _observers = new List<IObserver>();
    private string _state;

    public string State
    {
        get { return _state; }
        set
        {
            _state = value;
            Notify();
        }
    }

    public void Attach(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void Detach(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (IObserver observer in _observers)
        {
            observer.Update();
        }
    }
}

// 观察者接口
public interface IObserver
{
    void Update();
}

// 具体观察者类
public class ConcreteObserver : IObserver
{
    private string _name;
    private ConcreteSubject _subject;

    public ConcreteObserver(string name, ConcreteSubject subject)
    {
        _name = name;
        _subject = subject;
    }

    public void Update()
    {
        Console.WriteLine($"Observer {_name} received state: {_subject.State}");
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver observerA = new ConcreteObserver("A", subject);
        ConcreteObserver observerB = new ConcreteObserver("B", subject);

        subject.Attach(observerA);
        subject.Attach(observerB);

        subject.State = "State 1";
        // 输出:
        // Observer A received state: State 1
        // Observer B received state: State 1

        subject.State = "State 2";
        // 输出:
        // Observer A received state: State 2
        // Observer B received state: State 2

        subject.Detach(observerB);

        subject.State = "State 3";
        // 输出:
        // Observer A received state: State 3
    }
}

解释

在上述示例中,ISubject是主题接口,定义了对观察者的操作方法;ConcreteSubject是具体主题类,实现了主题接口,并在状态改变时通知所有观察者。IObserver是观察者接口,定义了观察者的更新方法;ConcreteObserver是具体观察者类,实现了观察者接口,并在收到通知时输出主题的状态。在客户端中,首先创建主题和观察者对象,然后将观察者注册到主题上,最后可以通过改变主题的状态来触发对应观察者的更新。

7. 状态模式(State)

状态模式允许对象在其内部状态发生改变时改变其行为,使得对象看起来像是在修改了其回归类。

示例代码

// 状态接口
public interface IState
{
    void Handle(Context context);
}

// 具体状态类
public class ConcreteStateA : IState
{
    public void Handle(Context context)
    {
        Console.WriteLine("State A handling");
        context.State = new ConcreteStateB();
    }
}

public class ConcreteStateB : IState
{
    public void Handle(Context context)
    {
        Console.WriteLine("State B handling");
        context.State = new ConcreteStateA();
    }
}

// 上下文类
public class Context
{
    public IState State { get; set; }

    public Context(IState initState)
    {
        State = initState;
    }

    public void Request()
    {
        State.Handle(this);
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        Context context = new Context(new ConcreteStateA());

        context.Request();
        // 输出: State A handling

        context.Request();
        // 输出: State B handling

        context.Request();
        // 输出: State A handling
    }
}

解释

在上述示例中,IState是状态接口,定义了状态的处理方法Handle()ConcreteStateAConcreteStateB是具体状态类,实现了状态接口,并根据自身的逻辑处理状态的改变。Context类是上下文类,内部存储当前的状态,并在请求方法Request()中调用当前状态的处理方法。在客户端中,首先创建上下文对象和初始状态对象,然后可以通过调用上下文的请求方法来触发状态的改变,从而导致不同的行为。

8. 策略模式(Strategy)

策略模式定义了一系列的算法,将每个算法都封装起来,并使它们可以相互替换。

示例代码

// 策略接口
public interface IStrategy
{
    void Execute();
}

// 具体策略类
public class ConcreteStrategyA : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Executing Strategy A");
    }
}

public class ConcreteStrategyB : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Executing Strategy B");
    }
}

// 上下文类
public class Context
{
    private IStrategy _strategy;

    public Context(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void ExecuteStrategy()
    {
        _strategy.Execute();
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        IStrategy strategyA = new ConcreteStrategyA();
        IStrategy strategyB = new ConcreteStrategyB();

        Context context = new Context(strategyA);
        // 输出: Executing Strategy A
        context.ExecuteStrategy();

        context = new Context(strategyB);
        // 输出: Executing Strategy B
        context.ExecuteStrategy();
    }
}

解释

在上述示例中,IStrategy是策略接口,定义了算法的执行方法Execute()ConcreteStrategyAConcreteStrategyB是具体策略类,分别实现了策略接口,并提供不同的算法实现。Context类是上下文类,持有一个策略对象,并执行策略对象的算法。客户端首先创建不同的策略对象,然后根据需要将不同的策略对象传递给上下文,并调用上下文的执行方法来执行具体的算法。

9. 模板方法模式(Template Method)

模板方法模式定义了一个操作中的算法框架,将一些步骤延迟到子类中实现。

示例代码

// 抽象类
public abstract class AbstractClass
{
    public void TemplateMethod()
    {
        Console.WriteLine("Template Method - Step 1");
        PrimitiveOperation1();
        Console.WriteLine("Template Method - Step 2");
        PrimitiveOperation2();
    }

    protected abstract void PrimitiveOperation1();
    protected abstract void PrimitiveOperation2();
}

// 具体类
public class ConcreteClassA : AbstractClass
{
    protected override void PrimitiveOperation1()
    {
        Console.WriteLine("Concrete Class A - Primitive Operation 1");
    }

    protected override void PrimitiveOperation2()
    {
        Console.WriteLine("Concrete Class A - Primitive Operation 2");
    }
}

public class ConcreteClassB : AbstractClass
{
    protected override void PrimitiveOperation1()
    {
        Console.WriteLine("Concrete Class B - Primitive Operation 1");
    }

    protected override void PrimitiveOperation2()
    {
        Console.WriteLine("Concrete Class B - Primitive Operation 2");
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        AbstractClass abstractClass = new ConcreteClassA();
        // 输出:
        // Template Method - Step 1
        // Concrete Class A - Primitive Operation 1
        // Template Method - Step 2
        // Concrete Class A - Primitive Operation 2
        abstractClass.TemplateMethod();

        abstractClass = new ConcreteClassB();
        // 输出:
        // Template Method - Step 1
        // Concrete Class B - Primitive Operation 1
        // Template Method - Step 2
        // Concrete Class B - Primitive Operation 2
        abstractClass.TemplateMethod();
    }
}

解释

在上述示例中,AbstractClass是抽象类,定义了模板方法TemplateMethod(),该方法包含了一系列的步骤,并调用了抽象方法PrimitiveOperation1()PrimitiveOperation2()ConcreteClassAConcreteClassB是具体类,继承自抽象类,并实现了抽象方法。客户端中,首先创建具体类的对象,并调用其模板方法,从而按照固定的步骤执行特定的算法。

10. 访问者模式(Visitor)

访问者模式定义了一种在不改变被访问对象结构的前提下,可以对该对象的元素进行操作的方法。

示例代码

// 元素接口
public interface IElement
{
    void Accept(IVisitor visitor);
}

// 具体元素类
public class ConcreteElementA : IElement
{
    public void Accept(IVisitor visitor)
    {
        visitor.VisitConcreteElementA(this);
    }
}

public class ConcreteElementB : IElement
{
    public void Accept(IVisitor visitor)
    {
        visitor.VisitConcreteElementB(this);
    }
}


// 访问者接口
public interface IVisitor
{
    void VisitConcreteElementA(ConcreteElementA element);
    void VisitConcreteElementB(ConcreteElementB element);
}

// 具体访问者类
public class ConcreteVisitor : IVisitor
{
    public void VisitConcreteElementA(ConcreteElementA element)
    {
        Console.WriteLine("Visiting Concrete Element A");
    }
  
    public void VisitConcreteElementB(ConcreteElementB element)
    {
        Console.WriteLine("Visiting Concrete Element B");
    }
}

// 对象结构类
public class ObjectStructure
{
    private List<IElement> _elements = new List<IElement>();

    public void AddElement(IElement element)
    {
        _elements.Add(element);
    }

    public void Accept(IVisitor visitor)
    {
        foreach (IElement element in _elements)
        {
            element.Accept(visitor);
        }
    }
}

// 客户端类
public class Client
{
    public void Main()
    {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.AddElement(new ConcreteElementA());
        objectStructure.AddElement(new ConcreteElementB());

        IVisitor visitor = new ConcreteVisitor();
        objectStructure.Accept(visitor);
        // 输出:
        // Visiting Concrete Element A
        // Visiting Concrete Element B
    }
}

解释

在上述示例中,IElement是元素接口,定义了对元素的访问方法Accept()ConcreteElementAConcreteElementB是具体元素类,实现了元素接口,并在自己的访问方法中调用访问者的具体访问方法。IVisitor是访问者接口,定义了访问者的具体访问方法;ConcreteVisitor是具体访问者类,实现了访问者接口,并在每个具体访问方法中对元素进行访问。ObjectStructure是对象结构类,包含了需要被访问的元素,并提供对外的访问方法。在客户端中,首先创建对象结构对象和具体元素对象,并将元素对象加入到对象结构中,然后通过创建具体访问者对象来访问对象结构中的元素。


C#常见的设计模式-行为型模式_第2张图片

你可能感兴趣的:(C#,c#,设计模式,观察者模式,访问者模式,策略模式,迭代器模式,状态模式)