0%

状态模式 - 行为型模式的状态切换之旅

在软件设计中,状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。状态模式的核心思想是将对象的行为与其状态分离,使得在不同的状态下可以选择不同的行为。本文将深入讨论状态模式的概念、实现方式以及在实际应用中的使用场景。

状态模式的概念

状态模式(State Pattern)是一种行为型设计模式,其核心思想是允许一个对象在其内部状态改变时改变其行为。状态模式将对象的状态和行为分离,使得对象在不同的状态下可以选择不同的行为。状态模式主要包括三个角色:上下文(Context)、抽象状态(State)和具体状态(ConcreteState)。

状态模式的 UML 类图

classDiagram
    class Context {
        - state: State
        + Request(): void
        + SetState(state: State): void
    }

    class State {
        + Handle(context: Context): void
    }

    class ConcreteStateA
    class ConcreteStateB

    Context --> State
    State <|.. ConcreteStateA
    State <|.. ConcreteStateB

状态模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;

// 抽象状态类
public abstract class State
{
public abstract void Handle(Context context);
}

// 具体状态类 A
public class ConcreteStateA : State
{
public override void Handle(Context context)
{
Console.WriteLine("Handling with ConcreteStateA");
// 在具体状态类中可以改变上下文的状态
context.SetState(new ConcreteStateB());
}
}

// 具体状态类 B
public class ConcreteStateB : State
{
public override void Handle(Context context)
{
Console.WriteLine("Handling with ConcreteStateB");
// 在具体状态类中可以改变上下文的状态
context.SetState(new ConcreteStateA());
}
}

// 上下文类
public class Context
{
private State state;

public Context(State initialState)
{
this.state = initialState;
}

public void Request()
{
// 上下文类将请求委托给当前状态处理
state.Handle(this);
}

public void SetState(State newState)
{
this.state = newState;
}
}

状态模式的应用场景

状态模式适用于以下情况:

  1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
  2. 一个操作中含有大量的条件语句,并且这些条件语句的目的是根据对象的状态选择不同的行为。
  3. 一个对象需要根据内部状态来改变它的状态。

状态模式的优势

  1. 封装性好: 状态模式将一个对象的状态封装到不同的状态类中,使得每个状态类的实现都相对独立,便于维护和扩展。
  2. 可扩展性: 可以轻松地增加新的状态类,扩展系统的功能。
  3. 避免条件语句: 状态模式通过将不同的状态分离,避免了大量的条件语句,使得代码更加清晰。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Program
{
static void Main()
{
// 创建上下文对象,初始状态为 ConcreteStateA
Context context = new Context(new ConcreteStateA());

// 发起请求,由 ConcreteStateA 处理
context.Request();

// 发起请求,由 ConcreteStateB 处理
context.Request();
}
}

总结

状态模式是一种行为型设计模式,通过将对象的状态和行为分离,使得对象在不同的状态下可以选择不同的行为。状态模式适用于一个对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为的场景。在实际应用中,状态模式常用于处理有限状态机、状态切换等场景。

中介者模式 - 行为型模式的协调调停者

在软件设计中,中介者模式是一种行为型设计模式,它定义了一个中介者对象,该对象封装了一组对象之间的交互方式。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调,降低了对象之间的耦合性。本文将深入讨论中介者模式的概念、实现方式以及在实际应用中的使用场景。

中介者模式的概念

中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是定义一个中介者对象,该对象封装了一组对象之间的交互方式。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调。这样的设计降低了对象之间的耦合性,使得系统更加灵活和易于维护。

中介者模式的 UML 类图

classDiagram
    class Mediator {
        + RegisterColleague(colleague: Colleague): void
        + SendMessage(colleague: Colleague, message: string): void
    }

    class Colleague {
        - mediator: Mediator
        + Send(message: string): void
        + Receive(message: string): void
    }

    class ConcreteMediator {
        - colleagues: List
        + RegisterColleague(colleague: Colleague): void
        + SendMessage(colleague: Colleague, message: string): void
    }

    class ConcreteColleagueA
    class ConcreteColleagueB

    Mediator <|.. ConcreteMediator
    Colleague <|.. ConcreteColleagueA
    Colleague <|.. ConcreteColleagueB

中介者模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;

// 抽象中介者
public interface Mediator
{
void RegisterColleague(Colleague colleague);
void SendMessage(Colleague colleague, string message);
}

// 抽象同事类
public abstract class Colleague
{
protected Mediator mediator;

public Colleague(Mediator mediator)
{
this.mediator = mediator;
}

public abstract void Send(string message);
public abstract void Receive(string message);
}

// 具体中介者
public class ConcreteMediator : Mediator
{
private List<Colleague> colleagues;

public ConcreteMediator()
{
this.colleagues = new List<Colleague>();
}

public void RegisterColleague(Colleague colleague)
{
colleagues.Add(colleague);
}

public void SendMessage(Colleague colleague, string message)
{
foreach (var c in colleagues)
{
if (c != colleague)
{
c.Receive(message);
}
}
}
}

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

public override void Send(string message)
{
Console.WriteLine("Colleague A sends message: " + message);
mediator.SendMessage(this, message);
}

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

// 具体同事类B
public class ConcreteColleagueB : Colleague
{
public ConcreteColleagueB(Mediator mediator) : base(mediator) { }

public override void Send(string message)
{
Console.WriteLine("Colleague B sends message: " + message);
mediator.SendMessage(this, message);
}

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

中介者模式的应用场景

中介者模式适用于以下情况:

  1. 一组对象之间存在复杂的交互关系,导致它们之间的通信结构复杂难以理解。
  2. 对象之间的交互行为需要随时变化,或者需要增加新的对象时。
  3. 系统中的对象由于通信关系过于紧密,导致它们之间的耦合性较高。

中介者模式的优势

  1. 降低耦合性: 中介者模式通过将对象之间的通信集中在中介者中,降低了对象之间的耦合性。
  2. 简化对象交互: 中介者模式将对象之间的交互方式封装在中介者中,使得对象之间的通信更加简单清晰。
  3. 易于扩展: 可以通过增加新的同事类和调整中介者的实现,轻松地扩展系统。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Program
{
static void Main()
{
// 创建具体中介者对象
ConcreteMediator mediator = new ConcreteMediator();

// 创建具体同事类对象,并注册到中介者
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.RegisterColleague(colleagueA);
mediator.RegisterColleague(colleagueB);

// 同事类之间通过中介者进行通信
colleagueA.Send("Hello from Colleague A");
colleagueB.Send("Hi from Colleague B");
}
}

总结

中介者模式是一种行为型设计模式,通过定义一个中介者对象,封装了一组对象之间的交互方式,降低了对象之间的耦合性。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调。在实际应用中

职责链模式 - 行为型模式的责任传递者

在软件设计中,职责链模式是一种行为型设计模式,它通过一系列处理对象组成的链条,依次处理请求,直到找到合适的处理者。职责链模式可以有效地解耦发送者和接收者,并允许多个对象处理同一个请求。本文将深入讨论职责链模式的概念、实现方式以及在实际应用中的使用场景。

职责链模式的概念

职责链模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是将处理对象组成一条链,依次处理请求,直到找到合适的处理者。每个处理对象都包含一个指向下一个处理对象的引用,形成一个处理链。请求从链的头部开始,沿着链条传递,直到有一个处理对象能够处理该请求。

职责链模式的 UML 类图

classDiagram
    class Handler {
        - successor: Handler
        + SetSuccessor(successor: Handler): void
        + HandleRequest(request: int): void
    }

    class ConcreteHandlerA {
        + HandleRequest(request: int): void
    }

    class ConcreteHandlerB {
        + HandleRequest(request: int): void
    }

    Handler <|-- ConcreteHandlerA
    Handler <|-- ConcreteHandlerB

职责链模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;

// 抽象处理者类
public abstract class Handler
{
protected Handler successor;

public void SetSuccessor(Handler successor)
{
this.successor = successor;
}

public abstract void HandleRequest(int request);
}

// 具体处理者A
public class ConcreteHandlerA : Handler
{
public override void HandleRequest(int request)
{
if (request >= 0 && request < 10)
{
Console.WriteLine($"Concrete Handler A handles request {request}");
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}

// 具体处理者B
public class ConcreteHandlerB : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine($"Concrete Handler B handles request {request}");
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}

职责链模式的应用场景

职责链模式适用于以下情况:

  1. 多个对象可以处理同一个请求,但具体由哪个对象处理在运行时确定。
  2. 系统需要动态地指定处理一个请求的对象集合。
  3. 请求的发送者和接收者之间需要解耦,使得系统更灵活。

职责链模式的优势

  1. 解耦发送者和接收者: 职责链模式可以有效地解耦请求的发送者和接收者,每个处理者只关心自己的处理逻辑。
  2. 灵活性和可扩展性: 可以动态地调整链上处理对象的顺序或者增加新的处理对象,提高系统的灵活性和可扩展性。
  3. 单一职责原则: 每个具体处理者都只负责自己能够处理的请求,符合单一职责原则。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Program
{
static void Main()
{
// 创建具体处理者对象
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();

// 设置处理链
handlerA.SetSuccessor(handlerB);

// 发送请求,实际上会从处理链的头部开始,依次尝试每个处理者
handlerA.HandleRequest(15);
}
}

总结

职责链模式是一种行为型设计模式,通过将处理对象组成一条链,依次处理请求,实现了请求的发送者和接收者的解耦。职责链模式在需要多个对象处理同一个请求,且具体处理对象在运行时确定的情景中有广泛的应用。在实际应用中,职责链模式需要注意设计链上处理对象的逻辑,以确保请求能够正确地被处理。

模板方法模式 - 行为型模式的骨架定义者

在软件设计中,模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将算法中的一些步骤延迟到子类中实现。模板方法模式允许子类在不改变算法结构的情况下重新定义算法中的某些步骤。本文将深入讨论模板方法模式的概念、实现方式以及在实际应用中的使用场景。

模板方法模式的概念

模板方法模式(Template Method Pattern)是一种行为型设计模式,其核心思想是定义一个算法的骨架,将算法中的一些步骤延迟到子类中实现。模板方法模式在父类中定义算法的结构,而将具体步骤的实现交给子类。这样,子类可以在不改变算法结构的情况下重新定义算法的某些步骤。

模板方法模式的 UML 类图

classDiagram
    class AbstractClass {
        # PrimitiveOperation1(): void
        # PrimitiveOperation2(): void
        + TemplateMethod(): void
    }

    class ConcreteClass {
        + PrimitiveOperation1(): void
        + PrimitiveOperation2(): void
    }

    AbstractClass <|-- ConcreteClass

模板方法模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;

// 抽象类
public abstract class AbstractClass
{
// 模板方法定义了算法的骨架,将某些步骤的实现交给子类
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
}

// 原语操作1,延迟到子类实现
protected abstract void PrimitiveOperation1();

// 原语操作2,延迟到子类实现
protected abstract void PrimitiveOperation2();
}

// 具体类
public class ConcreteClass : AbstractClass
{
// 实现原语操作1
protected override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClass Primitive Operation 1");
}

// 实现原语操作2
protected override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClass Primitive Operation 2");
}
}

模板方法模式的应用场景

模板方法模式适用于以下情况:

  1. 多个子类有共同的算法骨架,但其中某些步骤的实现可能不同。
  2. 不想让子类改变算法的骨架,只允许改变某些具体步骤的实现。
  3. 重构时,将相同的代码抽取到父类中,形成模板方法,提高代码的复用性。

模板方法模式的优势

  1. 代码复用: 模板方法模式将相同的算法骨架封装在父类中,提高了代码的复用性。
  2. 封装变化: 模板方法模式允许子类在不改变算法结构的情况下重新定义某些步骤的实现,封装了变化。
  3. 简化子类: 子类不需要关心算法的结构,只需实现具体步骤,简化了子类的设计。

使用示例

1
2
3
4
5
6
7
8
9
10
11
class Program
{
static void Main()
{
// 创建具体类对象
ConcreteClass concreteClass = new ConcreteClass();

// 调用模板方法,实际上会执行具体类中定义的算法骨架
concreteClass.TemplateMethod();
}
}

总结

模板方法模式是一种行为型设计模式,通过定义一个算法的骨架,将算法中的一些步骤延迟到子类中实现。模板方法模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤,提高了代码的复用性和灵活性。在实际应用中,模板方法模式常用于多个子类有共同的算法骨架,但其中某些步骤的实现可能不同的场景。

命令模式 - 行为型模式的请求发送者与接收者分离者

在软件设计中,命令模式是一种行为型设计模式,它将请求封装为一个对象,使得可以参数化客户端对象,队列中存储请求,并且支持撤销操作。命令模式将请求的发送者和接收者解耦,使得系统更加灵活。本文将深入讨论命令模式的概念、实现方式以及在实际应用中的使用场景。

命令模式的概念

命令模式(Command Pattern)是一种行为型设计模式,其核心思想是将请求封装为一个对象,使得可以参数化客户端对象,队列中存储请求,并支持撤销操作。命令模式将请求的发送者和接收者解耦,使得系统更加灵活,能够支持命令的合成和扩展。

命令模式的 UML 类图

classDiagram
    class Command {
        + Execute(): void
        + Undo(): void
    }

    class ConcreteCommand {
        - receiver: Receiver
        + Execute(): void
        + Undo(): void
    }

    class Receiver {
        + Action(): void
    }

    class Invoker {
        - command: Command
        + SetCommand(command: Command): void
        + ExecuteCommand(): void
        + UndoCommand(): void
    }

    class Client

    Command <|.. ConcreteCommand
    ConcreteCommand --> Receiver
    Invoker --> Command

命令模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;

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

// 具体命令类
public class ConcreteCommand : Command
{
private Receiver receiver;

public ConcreteCommand(Receiver receiver)
{
this.receiver = receiver;
}

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

public void Undo()
{
// 提供撤销操作的具体实现
}
}

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

// 请求发送者类
public class Invoker
{
private Command command;

public void SetCommand(Command command)
{
this.command = command;
}

public void ExecuteCommand()
{
command.Execute();
}

public void UndoCommand()
{
command.Undo();
}
}

命令模式的应用场景

命令模式适用于以下情况:

  1. 需要将请求的发送者和接收者解耦,使得系统更加灵活。
  2. 需要支持请求的撤销操作。
  3. 需要支持命令的合成和扩展。
  4. 需要在不同的时间指定请求、将请求排队、记录请求等。

命令模式的优势

  1. 解耦性: 命令模式将请求的发送者和接收者解耦,使得系统更加灵活,易于扩展和维护。
  2. 可扩展性: 可以方便地增加新的命令类,实现对命令的扩展。
  3. 支持撤销操作: 可以实现命令的撤销操作,提供系统的可靠性。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Program
{
static void Main()
{
// 创建接收者对象
Receiver receiver = new Receiver();

// 创建具体命令对象,传入接收者对象
Command command = new ConcreteCommand(receiver);

// 创建请求发送者对象,传入具体命令对象
Invoker invoker = new Invoker();
invoker.SetCommand(command);

// 发送请求,实际上会执行接收者对象的操作
invoker.ExecuteCommand();
}
}

总结

命令模式是一种行为型设计模式,通过将请求封装为一个对象,实现了请求的发送者和接收者的解耦。命令模式支持撤销操作,并且易于扩展和维护。在实际应用中,命令模式常用于实现撤销、排队、记录日志等功能。

观察者模式 - 行为型模式的消息发布与订阅

在软件设计中,观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听并被通知某个主题对象的状态改变。观察者模式的核心思想是将主题和观察者分离,使得主题对象的状态改变可以通知到所有依赖于它的观察者对象。本文将深入讨论观察者模式的概念、实现方式以及在实际应用中的使用场景。

观察者模式的概念

观察者模式(Observer Pattern)是一种行为型设计模式,其核心思想是定义了一种一对多的依赖关系,让多个观察者对象同时监听并被通知某个主题对象的状态改变。观察者模式的主要角色包括主题(Subject)、具体主题(ConcreteSubject)、观察者(Observer)和具体观察者(ConcreteObserver)。

观察者模式的 UML 类图

classDiagram
    class Subject {
        + Attach(observer: Observer): void
        + Detach(observer: Observer): void
        + Notify(): void
    }

    class ConcreteSubject {
        - state: string
        - observers: List
        + GetState(): string
        + SetState(state: string): void
        + Attach(observer: Observer): void
        + Detach(observer: Observer): void
        + Notify(): void
    }

    class Observer {
        + Update(): void
    }

    class ConcreteObserver {
        - name: string
        - subject: ConcreteSubject
        + Update(): void
    }

    Subject <|.. ConcreteSubject
    Observer <|.. ConcreteObserver
    ConcreteObserver --> ConcreteSubject

观察者模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections.Generic;

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

// 具体主题类
public class ConcreteSubject : Subject
{
private string state;
private List<Observer> observers;

public ConcreteSubject()
{
this.observers = new List<Observer>();
}

public string GetState()
{
return state;
}

public void SetState(string state)
{
this.state = state;
Notify();
}

public void Attach(Observer observer)
{
observers.Add(observer);
}

public void Detach(Observer observer)
{
observers.Remove(observer);
}

public void Notify()
{
foreach (var observer in observers)
{
observer.Update();
}
}
}

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

// 具体观察者类
public class ConcreteObserver : Observer
{
private string name;
private ConcreteSubject subject;

public ConcreteObserver(string name, ConcreteSubject subject)
{
this.name = name;
this.subject = subject;
}

public void Update()
{
Console.WriteLine($"Observer {name} received the updated state: {subject.GetState()}");
}
}

观察者模式的应用场景

观察者模式适用于以下情况:

  1. 一个对象的状态改变需要通知其他对象,并且这些对象需要根据状态改变而做出相应的响应。
  2. 一个对象的改变需要同时影响其他对象,而且不知道有多少对象需要被通知。
  3. 一个对象向其他对象提供实时信息,而不知道这些对象是谁。

观察者模式的优势

  1. 解耦性强: 观察者模式将主题和观察者解耦,使得它们之间的关系更加灵活。
  2. 扩展性好: 可以在系统中很容易地增加新的观察者,扩展系统的功能。
  3. 实现消息发布与订阅: 观察者模式实现了一种简单的消息发布与订阅机制,适用于需要实现事件处理机制的场景。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{
static void Main()
{
// 创建具体主题对象
ConcreteSubject subject = new ConcreteSubject();

// 创建具体观察者对象,并注册到主题
ConcreteObserver observerA = new ConcreteObserver("Observer A", subject);
ConcreteObserver observerB = new ConcreteObserver("Observer B", subject);
subject.Attach(observerA);
subject.Attach(observerB);

// 设置主题状态,观察者收到通知并更新
subject.SetState("New State");
}
}

总结

观察者模式是一种行为型设计模式,通过定义了一种一对多的依赖关系,让多个观察者对象同时监听并被通知某个主题对象的状态改变。观察者模式适用于实现消息发布与订阅、解耦主题和观察者的场景。在实际应用中,观察者模式常用于实现事件处理机制、图形界面组件的刷新等场景。

解释器模式 - 行为型模式的语言解释者

在软件设计中,解释器模式是一种行为型设计模式,它定义了一种语言文法的表示,并提供了解释器来解释该语言中的句子。解释器模式可以用于实现自定义语言、配置文件解析等场景。本文将深入讨论解释器模式的概念、实现方式以及在实际应用中的使用场景。

解释器模式的概念

解释器模式(Interpreter Pattern)是一种行为型设计模式,其核心思想是定义一种语言文法的表示,并提供一个解释器来解释该语言中的句子。解释器模式主要用于实现自定义语言、配置文件解析、正则表达式等场景,通过定义语法规则和解释器,实现对特定语言的解释和执行。

解释器模式的 UML 类图

classDiagram
    class Context {
        - input: string
        + Context(input: string)
        + GetNextToken(): string
        + GetToken(): string
    }

    class AbstractExpression {
        + Interpret(context: Context): void
    }

    class TerminalExpression {
        + Interpret(context: Context): void
    }

    class NonterminalExpression {
        + Interpret(context: Context): void
    }

    Context --> AbstractExpression
    AbstractExpression <|-- TerminalExpression
    AbstractExpression <|-- NonterminalExpression

解释器模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;

// 上下文类,保存解释器需要的信息
public class Context
{
private readonly string input;
private int currentTokenIndex;

public Context(string input)
{
this.input = input;
this.currentTokenIndex = 0;
}

// 获取下一个标记
public string GetNextToken()
{
// 简化示例,实际中可能需要更复杂的逻辑
if (currentTokenIndex < input.Length)
{
return input[currentTokenIndex++].ToString();
}
return null;
}

// 获取当前标记
public string GetToken()
{
// 简化示例,实际中可能需要更复杂的逻辑
if (currentTokenIndex < input.Length)
{
return input[currentTokenIndex].ToString();
}
return null;
}
}

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

// 终结符表达式类
public class TerminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
string token = context.GetToken();
if (token != null)
{
Console.WriteLine($"Terminal Expression interprets token: {token}");
}
}
}

// 非终结符表达式类
public class NonterminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
string token = context.GetToken();
if (token != null)
{
Console.WriteLine($"Nonterminal Expression interprets token: {token}");
}
}
}

解释器模式的应用场景

解释器模式适用于以下情况:

  1. 需要实现自定义语言,且语言规则相对简单。
  2. 需要解析和执行配置文件,例如 XML 配置文件。
  3. 需要实现特定领域的脚本语言,如数学表达式解析。

解释器模式的优势

  1. 灵活性: 解释器模式允许动态改变语言规则,灵活适应不同的需求。
  2. 可扩展性: 可以轻松地扩展语言中的语法规则,增加新的表达式类型。
  3. 可维护性: 解释器模式将语法规则和解释过程分离,易于维护和扩展。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Program
{
static void Main()
{
// 创建上下文对象,传入待解释的语言
Context context = new Context("A B C D");

// 创建终结符和非终结符表达式对象
AbstractExpression terminalExpression = new TerminalExpression();
AbstractExpression nonterminalExpression = new NonterminalExpression();

// 解释语言中的每个标记
while (context.GetToken() != null)
{
// 判断标记类型,选择不同的表达式进行解释
if (context.GetToken() == "A" || context.GetToken() == "B")
{
terminalExpression.Interpret(context);
}
else
{
nonterminalExpression.Interpret(context);
}
}
}
}

总结

解释器模式是一种行为型设计模式,通过定义一种语言文法的表示,并提供一个解释器来解释该语言中的句子。解释器模式主要用于实现自定义语言、配置文件解析等场景,通过定义语法规则和解释器,实现对特定语言的解释和执行。在实际应用中,解释器模式需要根据具体场景灵活设计语法规则和解释器,以满足不同领域的需求。

访问者模式 - 行为型模式的灵活扩展

在软件设计中,访问者模式是一种行为型设计模式,它表示一个操作用于处理对象结构中的各元素,可以在不改变这些元素的类的前提下定义这些操作。访问者模式的核心思想是将数据结构与数据操作分离,使得数据结构可以独立于数据操作的变化。本文将深入讨论访问者模式的概念、实现方式以及在实际应用中的使用场景。

访问者模式的概念

访问者模式(Visitor Pattern)是一种行为型设计模式,其核心思想是表示一个操作用于处理对象结构中的各元素,可以在不改变这些元素的类的前提下定义这些操作。访问者模式主要包括四个角色:访问者(Visitor)、具体访问者(ConcreteVisitor)、元素(Element)和具体元素(ConcreteElement)。

访问者模式的 UML 类图

classDiagram
    class Visitor {
        + VisitConcreteElementA(element: ConcreteElementA): void
        + VisitConcreteElementB(element: ConcreteElementB): void
    }

    class ConcreteVisitor {
        + VisitConcreteElementA(element: ConcreteElementA): void
        + VisitConcreteElementB(element: ConcreteElementB): void
    }

    class Element {
        + Accept(visitor: Visitor): void
    }

    class ConcreteElementA {
        + Accept(visitor: Visitor): void
    }

    class ConcreteElementB {
        + Accept(visitor: Visitor): void
    }

    Visitor <|.. ConcreteVisitor
    Element <|.. ConcreteElementA
    Element <|.. ConcreteElementB

访问者模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;

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

// 具体访问者类
public class ConcreteVisitor : Visitor
{
public void VisitConcreteElementA(ConcreteElementA element)
{
Console.WriteLine("Visitor is visiting ConcreteElementA");
}

public void VisitConcreteElementB(ConcreteElementB element)
{
Console.WriteLine("Visitor is visiting ConcreteElementB");
}
}

// 元素接口
public interface Element
{
void Accept(Visitor visitor);
}

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

// 具体元素类 B
public class ConcreteElementB : Element
{
public void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
}

访问者模式的应用场景

访问者模式适用于以下情况:

  1. 一个对象结构包含多个类型的对象,且需要对这些对象进行不同的处理。
  2. 需要对对象结构中的元素进行频繁变化的操作。
  3. 对象结构中的元素类的个数比较稳定,但其行为操作算法经常变化。

访问者模式的优势

  1. 解耦性好: 访问者模式将数据结构与数据操作分离,使得数据结构可以独立于数据操作的变化。
  2. 可扩展性: 可以在不修改元素类的前提下增加新的访问者,实现对元素类的新的操作。
  3. 灵活性: 可以通过不同的具体访问者来实现不同的业务操作,达到灵活扩展的目的。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Program
{
static void Main()
{
// 创建具体元素对象
ConcreteElementA elementA = new ConcreteElementA();
ConcreteElementB elementB = new ConcreteElementB();

// 创建具体访问者对象
ConcreteVisitor visitor = new ConcreteVisitor();

// 元素接受访问者的访问
elementA.Accept(visitor);
elementB.Accept(visitor);
}
}

总结

访问者模式是一种行为型设计模式,通过将数据结构与数据操作分离,使得数据结构可以独立于数据操作的变化。访问者模式适用于一个对象结构包含多个类型的对象,且需要对这些对象进行不同的处理的场景。在实际应用中,访问者模式常用于处理复杂的对象结构、业务规则的动态变化等场景。

迭代器模式 - 行为型模式的元素访问者

在软件设计中,迭代器模式是一种行为型设计模式,它提供一种顺序访问集合对象元素的方法,而不暴露集合的内部表示。迭代器模式使得可以在不知道集合内部结构的情况下,按顺序访问集合中的元素。本文将深入讨论迭代器模式的概念、实现方式以及在实际应用中的使用场景。

迭代器模式的概念

迭代器模式(Iterator Pattern)是一种行为型设计模式,其核心思想是提供一种顺序访问集合对象元素的方法,而不暴露集合的内部表示。迭代器模式将对集合元素的遍历与集合的具体实现分离,使得可以在不知道集合内部结构的情况下,按顺序访问集合中的元素。

迭代器模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;

// 抽象迭代器接口
public interface Iterator
{
object Next();
bool HasNext();
}

// 具体迭代器类
public class ConcreteIterator : Iterator
{
private int index;
private ConcreteAggregate aggregate;

public ConcreteIterator(ConcreteAggregate aggregate)
{
this.index = 0;
this.aggregate = aggregate;
}

public object Next()
{
if (HasNext())
{
return aggregate.GetItemAt(index++);
}
return null;
}

public bool HasNext()
{
return index < aggregate.Count();
}
}

// 抽象集合接口
public interface Aggregate
{
Iterator CreateIterator();
}

// 具体集合类
public class ConcreteAggregate : Aggregate
{
private List<object> items;

public ConcreteAggregate()
{
this.items = new List<object>();
}

public void AddItem(object item)
{
items.Add(item);
}

public int Count()
{
return items.Count;
}

public object GetItemAt(int index)
{
return items[index];
}

public Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
}

迭代器模式的应用场景

迭代器模式适用于以下情况:

  1. 需要提供一种统一的方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。
  2. 需要对聚合对象的遍历操作进行抽象,使得可以在不依赖具体聚合类型的情况下遍历聚合对象。
  3. 需要支持多种不同遍历方式,如正序遍历、倒序遍历等。

迭代器模式的优势

  1. 简化客户端代码: 迭代器模式将对集合元素的遍历与集合的具体实现分离,简化了客户端代码。
  2. 支持多种遍历方式: 可以轻松地扩展或修改迭代器,支持多种不同的遍历方式。
  3. 隔离集合的具体实现: 客户端只需要通过迭代器接口访问集合元素,不需要关心集合的具体实现。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program
{
static void Main()
{
// 创建具体集合对象
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.AddItem("Item 1");
aggregate.AddItem("Item 2");
aggregate.AddItem("Item 3");

// 创建迭代器对象
Iterator iterator = aggregate.CreateIterator();

// 使用迭代器顺序访问集合元素
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
}
}

总结

迭代器模式是一种行为型设计模式,通过提供一种顺序访问集合对象元素的方法,将对集合元素的遍历与集合的具体实现分离。迭代器模式简化了客户端代码,支持多种遍历方式,隔离了集合的具体实现。在实际应用中,迭代器模式常用于处理集合元素的遍历和访问。

策略模式 - 行为型模式的智慧选择

在软件设计中,策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,使得客户端可以根据需要选择不同的算法。本文将深入讨论策略模式的概念、实现方式以及在实际应用中的使用场景。

策略模式的概念

策略模式(Strategy Pattern)是一种行为型设计模式,其核心思想是定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式使得算法的变化独立于使用算法的客户端,客户端可以根据需要在运行时选择不同的算法。策略模式主要包括三个角色:环境类(Context)、抽象策略类(Strategy)和具体策略类(ConcreteStrategy)。

策略模式的 UML 类图

classDiagram
    class Context {
        - strategy: Strategy
        + SetStrategy(strategy: Strategy): void
        + ExecuteStrategy(): void
    }

    class Strategy {
        + Execute(): void
    }

    class ConcreteStrategyA
    class ConcreteStrategyB

    Context --> Strategy
    Strategy <|.. ConcreteStrategyA
    Strategy <|.. ConcreteStrategyB

策略模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;

// 抽象策略类
public interface Strategy
{
void Execute();
}

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

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

// 环境类
public class Context
{
private Strategy strategy;

public void SetStrategy(Strategy strategy)
{
this.strategy = strategy;
}

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

策略模式的应用场景

策略模式适用于以下情况:

  1. 一个系统需要动态地在多个算法中选择一个。
  2. 一个对象有许多行为,而在不同的情况下只有其中一种行为能够生效。
  3. 系统需要在运行时根据环境状态切换算法。

策略模式的优势

  1. 增加新的策略: 策略模式允许新增加的策略类,使得系统更加灵活和易于扩展。
  2. 算法替换: 策略模式使得算法的变化独立于使用算法的客户端,客户端可以根据需要选择不同的算法。
  3. 避免条件语句: 策略模式可以避免大量的条件语句,使得代码更加清晰。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Program
{
static void Main()
{
// 创建环境对象
Context context = new Context();

// 设置具体策略类 A,执行策略
context.SetStrategy(new ConcreteStrategyA());
context.ExecuteStrategy();

// 设置具体策略类 B,执行策略
context.SetStrategy(new ConcreteStrategyB());
context.ExecuteStrategy();
}
}

总结

策略模式是一种行为型设计模式,通过将算法封装成独立的策略类,使得算法的变化独立于使用算法的客户端。策略模式适用于一个系统需要在多个算法中选择一个,或者一个对象有多个行为,但在不同的情况下只有其中一种行为生效的场景。在实际应用中,策略模式常用于实现算法的动态切换、行为的灵活组合等场景。