设计模式深入学习--Chain of Responsibility 职责链模式职责链模式(行为型模式)

   这次和大家一起学习一下 职责链设计模式。职责链设计模式非常好用,尤其是在做逻辑判断处理很多的情况下,比如一些AI的设计,配合FSM状态机可以做到一个入门级AI的小机器人。后面就用cs的ai敌人来大概讲解下职责链模式的用法。首先我们来看下职责链示例的代码:

/// <summary>
/// Handler类 定义一个处理请示的接口
/// </summary>
abstract class Handler
{
    protected Handler successor;
 
    public void SetSuccessor(Handler successor)
    {
        this.successor = successor;
    }
 
    public abstract void HandleRequest(int request);
}
 
class ConcreteHandler1 : Handler  //一级处理 处理0到10
{
    public override void HandleRequest(int request)
    {
        if (request >= 0 && request <= 10)  //处理自己能力或者职责范围内的事情
        {
            Console.WriteLine(this.GetType().Name + "处理请求" + request);
        }
        else if (successor != null)  //扛不住了 如果有老大 丢给老大处理
        {
            successor.HandleRequest(request);
        }
    }
}
 
class ConcreteHandler2 : Handler   //二级处理 处理10到20之间
{
    public override void HandleRequest(int request)
    {
        if (request >= 10 && request < 20)
        {
            Console.WriteLine(this.GetType().Name + "处理请求" + request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
 
    }
}
 
 
class ConcreteHandler3 : Handler   //三级处理 处理20到30之间
{
    public override void HandleRequest(int request)
    {
        if (request >= 20 && request < 30)
        {
            Console.WriteLine(this.GetType().Name + "处理请求" + request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
 
    }
}

           我们先声明了一个Handler 接口, 里面还包含了一个和自己一样的类,作为下一级处理程序 还有一个HandleRequest 方法,用来代表自己要处理逻辑的方法, 然后和三个实体类都继承了Handler 接口,分别是小中大 三个处理程序,小处理0到10数字,中处理11到20,大的处理21到30 ,现在到Main方法看看。

Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);
 
        int[] requests = { 2, 5, 16, 22, 18, 3, 24, 56 };
 
        foreach (int request in requests)
        {
            h1.HandleRequest(request);
        }
        Console.ReadKey();
           我们new 3个实体类,h2作为h1的下级处理程序,h3作为h2的下级处理程序。然后用循环把 数组的数字传入h1的处理方法。 运行结果如下:

 

     每个实体类就很好的处理了自己该做的逻辑处理,而不会处理的就转移到下一层给其他逻辑处理去了。好了,原理大概就是这样,那现在我们来试试做个简单的cs的AI敌人逻辑看看,我们的AI敌人分为几段距离来做不同的反应,首先我们先声明一个距离处理模块,然后是一个近处距离处理类,和一个远处距离处理类。

/// <summary>
   /// 距离处理模块
   /// </summary>
   abstract class DistanceHandler
   {
       protected DistanceHandler successor;
 
       public void SetSuccessor(DistanceHandler successor)
       {
           this.successor = successor;
       }
 
       public abstract void HandleRequest(int distance);
   }
 
   /// <summary>
   /// 近处处理 处理近处战斗处理
   /// </summary>
   class NearHandler : DistanceHandler  
   {
       public override void HandleRequest(int distance)
       {
           if (distance >= 0 && distance <= 2)  //处理自己能力或者职责范围内的事情
           {
               Console.WriteLine(this.GetType().Name + "处理距离:" + distance+"的敌人使用匕首攻击");
           }
           else if (distance >= 2 && distance <= 10)
           {
               Console.WriteLine(this.GetType().Name + "处理距离:" + distance + "的敌人使用手枪攻击");
           }
           else //距离过远 
           {
               if (successor != null)  //如果有其他处理就让它接盘
               {
                   successor.HandleRequest(distance);
               }
               else //距离太远 又没人接盘 那就赶紧逃跑吧
               {
                   Console.WriteLine("打不过,赶紧跑");
               }
           }
       }
   }
 
   /// <summary>
   /// 远处处理 处理远处战斗处理
   /// </summary>
   class FarHandler : DistanceHandler  
   {
       public override void HandleRequest(int distance)
       {
           if (distance >= 10 && distance <= 100)   
           {
               Console.WriteLine(this.GetType().Name + "处理距离:" + distance + "的敌人使用主武器攻击");
           }
           else if (distance >= 100 && distance <= 300)
           {
               Console.WriteLine(this.GetType().Name + "处理距离:" + distance + "的敌人,如果没有狙击枪就躲起来守株待兔");
           }
           else //距离过远 
           {
               if (successor != null)  //如果有其他处理就让它接盘
               {
                   successor.HandleRequest(distance);
               }
               else //距离太远 又没人接盘  
               {
                   Console.WriteLine("这么远,还是找别人打好了");
               }
           }
       }
   }

          我们在近处判断,如果距离低于2米就使用匕首武器,(实际情况下 匕首武器也可以弄成一个二级类,从这一块跳转到匕首武器类的处理方法去)10米内就使用手枪武器(同上),如果距离太远,当前处理不过来,就给下一级处理,下一级就是远处战斗类。然后我们在Main方法看看:

DistanceHandler near = new NearHandler();
           FarHandler far = new FarHandler();
           near.SetSuccessor(far);  //近处战斗处理下层处理设置为远处战斗
 
           int[] disList = { 2, 4, 76, 34, 27, 49, 15, 456, 133 };
           foreach (int dis in disList)
           {
               near.HandleRequest(dis);
           }
           Console.ReadKey();
   我们声明了一个far 和near类。让far作为near的下级处理程序,下面声明disList 的数组,模拟敌人要处理的距离,然后在foreach循环传入。最后我们看看结果:  

   如果我们的AI在unity里面,加入自动寻路,判断能否打得过对方 在配合使用说明武器,一个AI模块就做好了(我之前的帖子有介绍过用A*做寻路的文章) 也有一篇介绍过一个简单的fsm状态机。喜欢的朋友可以回去找找。
好了,职责链模式的用法就介绍到这里了,后面我们再来回顾下职责链模式 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。职责链的好处就是使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构,结果是职责链可简化对象的互相连接,他们仅需保持一个指向其后继者的引用,而不需保持它的所有的候选接受者的引用,从而大大降低了耦合度。我们就可以随时增加或者修改一个请求的结构,增强了给对象指派职责的灵活性。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值