三十三.设计模式总结-行为型模式
设计模式总结
三.行为型模式
1,观察者模式
定义对象间的一种1:N的依赖关系,当1变化时,N会得到通知
优点:使用List记录这一组对象,在需要时使用foreach调用对象的方法
总结:特点较明显,在特定的情况下使用。
class Boss : Subject
{
private IList<Observer> observers=newList<Observer>();
private string action;
public void Attach(Observer observer){observers.Add(observer); }
public void Detach(Observer observer){observers.Remove(observer); }
public voidNotify(){foreach (Observer o in observers) {o.Update();}}
public string SubjectState{get { returnaction; }set { action = value; }}
}
2,模板方法
定义算法的骨架,将一些步骤延迟到子类中。使其可以重构算法的步骤。
优点:可以方便的重构算法的步骤
缺点:要把握好重构自由和重构复杂的度。
总结:利用模板方法延伸出来的不同子类,实现不同方法。
classchild : father
{
public override void Show2()
{
base.Show2();
Console.WriteLine("变变看");
}
}
3,命令模式
将请求封装为一个对象,从而可用不同的请求对其进行参数化
优点:较容易设计一个命令列队
较容易将命令记入日志
允许接收者决定是否响应请求
支持撤销和重做操作
加入新的具体命令不影响其他类
缺点:
总结:结构特点很明显,先记录命令,再统一执行
publicclass Waiter
{
privateIList<Command> order=new List<Command>();
public void SetOrder(Command command) //设置订单
{
if (command.ToString() == "**"){Console.WriteLine("鸡翅没了");}
else{order.Add(command); }
}
public void CancelOrder(Command command)//取消订单{order.Remove(command);}
public void Notify()//通知执行{foreach (Command c in order){c.ExcuteCommand();}}
}
4,状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
优点:当对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为
总结:当操作中包含庞大的多分支条件语句,且分支依赖于状态。需要将复杂的判断逻
辑转移到表示不同状态的一些列类中。
状态模式只实例化一个类,仅仅根据这个对象的状态,改变其行为
//维护一个ConcreteState子类的实例,定义当前的状态
class Context
{
private State state;
public Context(State state)//定义Context的初始状态
{ this.state = state; }
public State State//读写当前状态和设置新状态
{
get { return state; }
set {state = value;Console.WriteLine("当前状态:"+state.GetType().Name); }
}
//对请求做处理,并设置一下状态
public void Request(){state.Handle(this); }
}
classConcreteStateA : State
{
public override void Handle(Context context)
{context.State = newConcreteStateB();//设置下一状态}
}
5,职责链模式
将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
优点:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
判断在模式中判断
缺点:判断在模式中,判断的每个分支有对应的类
要确保能有类负责完成
总结:和状态模式一样都是解决复杂判断的模式。
但状态模式根据对象状态判断,且只有一个对象。
职责链模式主要由处理类判断是否处理,否则传递到下一处理类。
//处理请求的接口
abstract class Handler
{
protected Handler successor;
public void SetSuccessor(Handler successor)//设置继任者{this.successor = successor; }
public abstract void HandlerRequest(int request); //处理请求的抽象方法
}
class ConcreteHandler1:Handler// 有权处理0-10之间
{
public override void HandlerRequest(intrequest)
{
if (request >= 0 && request < 10)
{Console.WriteLine("{0}处理请求{1}",this.GetType().Name,request ); }
else if (successor != null) {successor.HandlerRequest(request);//转移到下一位}
}
}
6,解释器模式
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示
来解释语言中的句子。
优点:遍历所有add进去的方法,易扩展,易修改
缺点:对于很多的规则(方法)存在时,难以维护
综合:字符串匹配,判断Email,匹配电话号码等等。正则表达式就是解释器模式的一种应用
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); }
7,中介者模式
用一个中介对象封装一系列的对象交互。中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立改变他们之间的交互
优点:将复杂的通信置入中介者中,发送接收消息的对象减少了耦合
增加对象,修改逻辑也很方便。
消息发送接收,对象只需要知道中介者
缺点:很容易使用,也很容易误用。
定义良好但通信复杂时使用
当出现多对多时,就麻烦了
总结:不要急于使用中介者模式。要在定义非常明确下考虑。如果出现多对多,首先考
虑系统设计是否合理
class ConcreteMediator:Mediator//具体中介者类
{
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public ConcreteColleague1 Colleague1{set { colleague1 = value; }}
public ConcreteColleague2Colleague2{set { colleague2 = value; }}
public override void Send(string message,Colleague colleague)
{
if (colleague == colleague1) {colleague2.Notify(message); }
else{colleague1.Notify(message ); }
}
}
8,访问者模式
表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作。
优点:把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。
缺点:最复杂的一个设计模式
总结:适用于数据结构相对稳定的系统(很少很少使用)。除非必须用,要么不用。
增加具体Element是困难的,但增加依赖于复杂对象结构的构件的操作就变得很容
易。仅需增加一个新的访问者即可在一个对象结构上定义一个新的操作。
9,策略模式
定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。
优点:使算法独立于使用它的客户而变化
总结:类似有简单工厂,但是工厂类返回的是类的实例。策略模式仅返回方法。
classCashContext
{
private CashSuper cs;
public CashContext(CashSuper csuper) {this.cs = csuper; }
public double GetResult(double monty) {return cs.acceptCash(monty); }
}
10,备忘录模式
在不破坏封装性的前提下,捕获一个对象内部状态,并在该对象之外保存这个状态。以便将对象恢复到原先保存状态。
优点:在不破坏封装性的前提下。在该对象之外保存这个状态。
总结:一般都会遇到这种功能,但这个不破坏封装,就是自身可以记录和恢复。
优点明显,可以用来保存数据。
classOriginator
{
private string state;//保存的属性
public string State{get { return state; } set { state = value; }}
public Memento CreateMemento()//创建备忘,将数据导入实例化一个Memento对象
{ return (new Memento(state)); }
public void SetMemento(Memento memento)//恢复备忘录{state = memento.State; }
public void Show(){Console.WriteLine("State="+state); }
}
11,迭代器模式
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
优点:比如foreach().
总结:现在由于有了foreach存在已很少使用
IEumerator支持对非泛型集合的简单迭代接口。
如foreach(string i in Str){print i}
就是:
IEnumerator<string>e=Str.GetEnumerator();
While(e.MoveNext())
{
Printe.Current;
}
//迭代器抽象类
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库