设计模式行为型
- 一:概念
- 二:具体模式
- 2.1 分类方式
- 2.2 单一对象模式
- 2.2.1模板方法
- 2.2.1.1 基础概念
- 2.2.1.2 类图
- 2.2.1.3 代码
- 2.2.2 策略模式
- 2.2.2.1 概念 :
- 2.2.2.2类图:
- 2.2.2.3代码
- 2.2.3 状态模式
- 2.2.3.1概念
- 2.2.3.2类图
- 2.2.3.3代码
- 2.2.4 观察者模式
- 2.2.4.1概念
- 2.2.4.2 类图
- 2.4.4.3代码
- 2.2.5 备忘录
- 2.2.5.1 概念
- 2.2.5.2 类图
- 2.2.5.3 代码
- 2.2.6 中介者模式
- 2.2.6.1 概念
- 2.2.6.2 结构
- 2.2.6.3 类图
- 2.2.6.4 代码
- 迭代器模式
- 概念
- 类图
- 代码
- 解释器模式
- 概念
- 类图
- 代码
一:概念
行为型设计模式是一种关注对象之间通信和交互的设计模式。它们用于描述对象之间的算法和职责分配,以及如何在运行时刻实现这些职责和算法。常见的行为型设计模式包括:
单一对象模式:
- 模板方法模式(Template Method Pattern)
- 策略模式(Strategy Pattern)
- 状态模式(State Pattern)
- 职责链模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 解释器模式(Interpreter Pattern)
多个对象模式:
- 迭代器模式(Iterator Pattern)
- 观察者模式(Observer Pattern)
- 中介者模式(Mediator Pattern)
- 备忘录模式(Memento Pattern)
- 访问者模式(Visitor Pattern)
这些行为型设计模式分别有不同的应用场景和使用方法,开发人员可以根据具体的需求选择适合自己的设计模式。
二:具体模式
2.1 分类方式
行为型模式一般有三种分类方法,分别是:
- 基于职责分配的分类:这种分类方法根据对象职责的不同,将行为型设计模式分为负责主动行为的模式和负责被动行为的模式两类。负责主动行为的模式包括模板方法模式、命令模式、策略模式等,而负责被动行为的模式则包括观察者模式、迭代器模式、备忘录模式等。
- 基于交互方式的分类:这种分类方法根据对象之间的交互方式,将行为型设计模式分为同步交互型模式和异步交互型模式两类。同步交互型模式包括模板方法模式、命令模式、策略模式等,而异步交互型模式则包括观察者模式、中介者模式、访问者模式等。
- 基于对象数量的分类:这种分类方法根据参与设计模式的对象数量,将行为型设计模式分为单一对象模式和多个对象模式两类。单一对象模式包括模板方法模式、状态模式、策略模式等,而多个对象模式则包括迭代器模式、访问者模式、中介者模式等。
今天我们的讲解采用第三种分类方式,按照对象的数量进行分类
2.2 单一对象模式
2.2.1模板方法
2.2.1.1 基础概念
模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
2.2.1.2 类图
分析类图我们可以得知:父类给出的是抽象的算法骨架,具体的方法怎么做留给了具体的子类。
2.2.1.3 代码
internal class Program
{
static void Main(string[] args)
{
//调用的时候想用那个具体子类的算法,实例化的就是那个子类的对象
AbstractClass class1 = new ConcreteClass();
class1.TemplateMethod();
}
}
abstract class AbstractClass
{
//定义的算法的执行骨架
public void TemplateMethod()
{
//算法的执行顺序
PrimitiveOperation1();
PrimitiveOperation2();
}
//子类里面可以更改的算法
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
}
//具体的子类
class ConcreteClass : AbstractClass
{
//具体子类实现
public override void PrimitiveOperation1()
{
Console.WriteLine("子类对算法的方法1的具体实现");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("子类对算法的方法2的具体实现");
}
}
模板方法如果想要扩展的话,就创建一个新的类来继承模板,将具体的算法的实现进行更改,使用的时候用哪个具体方法,实例化那个具体的对象就可以了。
2.2.2 策略模式
2.2.2.1 概念 :
策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
2.2.2.2类图:
策略模式主要由三部分构成
- 抽象策略(CashSuper)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(CashNormal1)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(CashContext)类:持有一个策略类的引用,最终给客户端调用。
2.2.2.3代码
static void Main(string[] args)
{
//这里调用的是第一个策略
CashSuper cashSuper = new CashNormal();
CashContext cashContext = new CashContext(cashSuper);
cashContext.GetResult();
}
abstract class CashSuper
{
//抽象的收费策略
public abstract void acceptCash();
}
class CashNormal : CashSuper
{
//第一种具体策略
public override void acceptCash()
{
Console.WriteLine("这是第一种策略");
}
}
class CashRebate : CashSuper
{
public override void acceptCash()
{
Console.WriteLine("这是第二种策略");
}
}
class CashReturn : CashSuper
{
public override void acceptCash()
{
Console.WriteLine("这是第三种策略");
}
}
//保存的策略类的引用
class CashContext
{
private CashSuper cashSuper;
//传入具体的策略对象
public CashContext(CashSuper cashSuper)
{
this.cashSuper = cashSuper;
}
//调用策略类的方法,传入的什么对象,就调用那个策略
public void GetResult()
{
cashSuper.acceptCash();
}
}
如果有新增业务的话,新增一个策略子类,继承抽象的策略类,调用的时候通过环境类进行调用就可以了。
2.2.3 状态模式
2.2.3.1概念
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
状态模式包含以下主要角色。
1.环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
2.抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
3.具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
2.2.3.2类图
2.2.3.3代码
namespace 状态模式
{
internal class Program
{
static void Main(string[] args)
{
Context c = new Context(new ConcreteStateA());
//开始调用,虽然看起来是同样的调用但是状态一直在变
c.Requet();
c.Requet();
c.Requet();
c.Requet();
}
}
class Context
{
private State state;
//定义初始状态
public Context(State state)
{
this.state = state;
}
//可读写属性状态
public State State
{
get { return state; }
set { state = value; }
}
//对请求做处理
public void Requet()
{
state.Handle(this);
}
}
abstract class State
{
public abstract void Handle(Context context);
}
//具体子类
class ConcreteStateA : State
{
public override void Handle(Context context)
{
//状态A的下一状态是状态B
context.State = new ConcreteStateB();
}
}
//具体子类B
class ConcreteStateB : State
{
public override void Handle(Context context)
{
//状态B的下一状态是状态A
context.State = new ConcreteStateA();
}
}
}
2.2.4 观察者模式
2.2.4.1概念
多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它是对象行为型模式。
2.2.4.2 类图
2.4.4.3代码
namespace 观察者模式
{
internal class Program
{
static void Main(string[] args)
{
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s,"X"));
s.Attach(new ConcreteObserver(s, "Y"));
s.Attach(new ConcreteObserver(s, "Z"));
s.SubjectState = "ABC";
s.Notify();
Console.ReadLine();
}
}
abstract class Observer
{
public abstract void Update();
}
class ConcreteObserver : Observer
{
private string name;
private string observerState;
private ConcreteSubject subject;
//构造函数
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
}
//通知
public override void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("观察者{0}的新状态是{1}",name,observerState);
}
public ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
}
class ConcreteSubject : Subject
{
private string subjectState; //具体被观察者状态
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
abstract class Subject
{
private IList<Observer> observers = new List<Observer>();
//增加观察者
public void Attach(Observer observer)
{
observers.Add(observer);
}
//移除观察者
public void Detach(Observer observer)
{
observers.Remove(observer);
}
//通知
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
}
}
2.2.5 备忘录
2.2.5.1 概念
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
2.2.5.2 类图
2.2.5.3 代码
namespace 备忘录模式
{
internal class Program
{
static void Main(string[] args)
{
Originator o = new Originator();
o.State = "On";
Caretaker c = new Caretaker();
c.Memento = o.CreteMemento();
o.State = "Off";
o.SetMemento(c.Memento);
}
}
class Memento
{
private string state;
public Memento(string state)
{
this.state = state;
}
public string State
{
get { return state; }
}
}
class Originator
{
private string state;
public string State
{
get { return state; }
set { state = value; }
}
public Memento CreteMemento()
{
return (new Memento(state));
}
public void SetMemento(Memento memento)
{
state = memento.State;
}
}
class Caretaker
{
private Memento memento;
public Memento Memento
{
get { return memento; }
set { memento = value; }
}
}
}
2.2.6 中介者模式
2.2.6.1 概念
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
2.2.6.2 结构
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者(Concrete Mediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
2.2.6.3 类图
2.2.6.4 代码
namespace 中介者模式
{
internal class Program
{
static void Main(string[] args)
{
}
}
//抽象中介者类
abstract class Mediator
{
public abstract void Send(string message, Colleague colleague);
}
//抽象同事类
abstract class Colleague
{
protected Mediator mediator;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
}
//具体中介者类
class ConcreteMediator : Mediator
{
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public ConcreteColleague1 Colleague1
{
set { colleague1 = value; }
}
public ConcreteColleague2 Colleague2
{
set { colleague2 = value; }
}
public override void Send(string message, Colleague colleague)
{
if (colleague == colleague1)
{
colleague2.Notify(message);
}
else
{
colleague1.Notify(message);
}
}
}
//具体同事对象
class ConcreteColleague1 : Colleague
{
public ConcreteColleague1(Mediator mediator) : base(mediator)
{ }
//中介者发送信息
public void Send(string message)
{
mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine("同事1得到信息"+ message);
}
}
//具体同事对象2
class ConcreteColleague2 : Colleague
{
public ConcreteColleague2(Mediator mediator) : base(mediator)
{ }
//中介者发送信息
public void Send(string message)
{
mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine("同事1得到信息" + message);
}
}
}
迭代器模式
概念
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式,
类图
代码
namespace 迭代器模式
{
internal class Program
{
static void Main(string[] args)
{
ConcreteAggregate a = new ConcreteAggregate();
a[0] = "大鸟";
a[0] = "小菜";
a[0] = "行李";
a[0] = "老外";
a[0] = "公交内部员工";
a[0] = "小偷";
Iterator i = new ConcreteIterator(a);
object item = i.First();
while (!i.IsDone())
{
Console.WriteLine("{0}请买车票!",i.CurrentItem());
i.Next();
}
}
}
//迭代器抽象类
abstract class Iterator
{
//统一的接口,定义了下一个对象,判断是否到结尾,当前对象等统一接口
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
//聚集抽象类
abstract class Aggregate
{
//创建迭代器
public abstract Iterator CreateIterator();
}
//创建迭代器
class ConcreteIterator : Iterator
{
private ConcreteAggregate aggregate;
private int current = 0;
public ConcreteIterator(ConcreteAggregate aggregate)
{
this.aggregate = aggregate;
}
public override object First()
{
return aggregate[0];
}
public override object Next()
{
object ret = null;
current++;
if (current<aggregate.Count)
{
ret = aggregate[current];
}
return ret;
}
public override bool IsDone()
{
return current >= aggregate.Count ? true : false;
}
public override object CurrentItem()
{
return aggregate[current];
}
}
//具体聚集类
class ConcreteAggregate : Aggregate
{
private IList<object> items = new List<object>();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public int Count
{
get { return items.Count; }
}
public object this[int index]
{
get { return items[index]; }
set { items.Insert(index, value); }
}
}
}
解释器模式
概念
给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
类图
代码
namespace 解释器模式
{
internal class Program
{
static void Main(string[] args)
{
Context context = new Context();
IList<AbstractExpression> list = new List<AbstractExpression>();
list.Add(new TerminalExpression());
list.Add(new NonterminalExpression());
list.Add(new TerminalExpression());
list.Add(new TerminalExpression());
foreach (AbstractExpression exp in list)
{
exp.Interpret(context);
}
Console.Read();
}
}
abstract class AbstractExpression
{
public abstract void Interpret(Context context);
}
class TerminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("终端解释器");
}
}
class NonterminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("非终端解释器");
}
}
class Context
{
private string input;
public string Input
{
get { return input; }
set { input = value; }
}
private string output;
public string Output
{
get { return output; }
set { output = value; }
}
}
}