首页 > 代码库 > 职责链模式之真假美猴王

职责链模式之真假美猴王

        孙悟空最终还是没有能逃脱如来的手掌心,因缘注定,皈依佛门,虽没有了做齐天大圣是的逍遥快活,也没有大闹天宫时的轰轰烈烈,但是现在有了更重要的一项任务,那就是普度众生,《 西游记》第五十七回,说是“六耳猕猴”化作孙悟空的摸样,伤了唐僧,后又和孙悟空大打出手。。。这位假孙悟空,实力不用多说了吧,和真孙悟空一般无二,大战孙悟空,闹到上天入地下海。在唐僧那:念紧箍咒,两个都喊疼,自然看不出哪个真假;到天宫:拖塔天王拿照妖镜照,也看不出;又到观音那:观音也看不出;最后到幽冥处阎罗那:经“谛听”听过之后,“谛听”却说:“我看出来了,却不敢说”,最后还是如来老佛爷道出六耳真身并用金钵盂罩住,才被孙悟空一棍子打死。这是整个故事,看似很简单,很完整,不过,我发现一个天大的伏笔。

        那就是,真假美猴王的故事和我们设计模式中的职责链模式有着异曲同工之妙,在面向对象程式设计里, 职责链模式是一种软件设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。官方定义---使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理她为止。来看一下职责链模式的结构图:

      

      在我们的实际生活中,我们也时常与职责链模式打着交道,比如类似“斗地主”这样的游戏中,小北出牌给他的下家,下家看看手中的牌,如果要不起上家的牌则将出牌请求再转发给他的下家,其下家再进行判断。一个循环下来,如果其他人都要不起该牌,则小北可以打出新的牌。在这个过程中,牌作为一个请求沿着一条链在传递,每一位纸牌的玩家都可以处理该请求。以我们上述真假美猴王的故事为例,看看我们的代码实现:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            
            {
                TangSeng = new TangSeng("唐僧");
                LiTianWang = new LiTianWang("李天王");
                GuangYin = new GuangYin("观音菩萨");
                DiTing = new DiTing("谛听");
                RuLai = new RuLai("如来"); 
              }

            //唐僧-->托塔李天王-->观音菩萨-->阎罗殿谛听-->如来佛祖
            judgement.TangSeng.NextImmortal = judgement.LiTianWang;
            judgement.LiTianWang.NextImmortal = judgement.GuanYin;
            judgement.TangSeng.NextImmortal = judgement.DiTing;
            judgement.DiTing.NextImmortal = judgement.RuLai;

            //两美猴王入场
            string SunWuKong = "SunWuKong",
            SixEarMonkey = "SixEarMonkey";
            //开始判断真假美猴王
            TheRealMonkeyKing RealMonkeyKing = judgement.Judge(SunWuKong, SixEarMonkey);
            Console.WriteLine();
            Console.WriteLine("Then,真正的美猴王是:" + RealMonkeyKing + "孙悟空");
           
            Console.ReadKey();
        }
    }

    //管理者,也就是众多神仙们
    abstract class Immortal
    {
        protected string name;
        //神仙的上级,这里的级别并没有严格的等级制度之分,只是因为该级别身份的神仙没有辨别出真假孙悟空
        protected Immortal superior;
        public Immortal (string name )
        {
            this.name = name;
        }
        //设置神仙的上级,这里的级别并没有严格的等级制度之分,只是因为该级别身份的神仙没有辨别出真假孙悟空
        public void SetSuperior(Immortal superior)
        {
            this.superior = superior;
        }
        
        //申请请求
        abstract public void RequestApplication(Request request);
        
    }
    //接下来,具体的神仙判断,首先是唐僧
    //唐僧
    public class TangSeng : Immortal 
    {

        /// 唐僧判断真假美猴王

        public TheRealMonkeyKing Handler(string SunWukong, string SixEarMonkey)
        {
            Console.WriteLine(" 唐僧念《紧箍儿咒》,二人一齐叫苦, 唐僧也不认得真假,两悟空打到李天王哪里");
            return NextImmortal.Immortal(SunWukong, SixEarMonkey);
        }

        // 指定下一路神仙  来判断真假美猴王
        public Immortal  NextImmortal { get; set; }

    }

    //托塔李天王
    public class LiTianWang : Immortal
    {

        //李天王判断真假美猴王

        public TheRealMonkeyKing Immortal(string SunWukong, string SixEarMonkey)
        {
            Console.WriteLine(" 李天王取照妖镜照住,镜中乃是两个孙悟空,毫发不差。玉帝亦辨不出,两悟空大战几百回合,来到了观音那里");
            return NextImmortal.Immortal(SunWukong, SixEarMonkey);
        }

        // 指定下一路神仙  来判断真假美猴王
        public Immortal NextImmortal { get; set; }

    }

    //观音
    public class Guanyin : Immortal 
    {

        //观音判断真假美猴王

        public TheRealMonkeyKing Immortal(string SunWukong, string SixEarMonkey)
        {
            Console.WriteLine(" 观音念《紧箍儿咒》,二人一齐叫苦, 唐僧也不认得真假,两悟空打到阎罗殿,谛听出来辨别");
            return NextImmortal.Immortal(SunWukong, SixEarMonkey);
        }

        // 指定下一路神仙来判断真假美猴王

        public Immortal  NextImmotal { get; set; }

    }

    //谛听
    public class DiTing :Immortal 
    {

        // 谛听判断真假美猴王

        public TheRealMonkeyKing Immortal(string SunWukong, string SixEarMonkey)
        {
            Console.WriteLine("阎罗殿的谛听可以分辨的出真假, 却不敢说出来,因为六耳猕猴的后台很强:如来是也");
            return NextImmortal.Immortal(SunWukong, SixEarMonkey);
        }

        // 指定下一路神仙  来判断真假美猴王

        public IHandler NextHandler { get; set; }
    }

    //如来
     public class RuLai :Immortal 
    {
     
        // 如来判断真假美猴王
    
        public TheRealMonkeyKing Immortal(string SunWukong, string SixEarMonkey)
        {
            Console.WriteLine(" 如来佛辨出真假,是所有神仙都没有听说过的新物种:六耳猕猴");
          
            return TheRealMonkeyKing.SunWukong;
          
        }
}
</span></span></span>
       对于真假美猴王这块的内容,大家争论不一,在真假美猴王事出之前,孙悟空并不完全都听唐僧的话,甚至有时候,还闹个小矛盾,导致唐僧只好念紧箍咒,典型的一个叛逆者形象。可自从真假美猴王事出之后,孙悟空从此保护唐僧安安分分。而以此事可以看出,孙悟空前后可判若两人。不排除,孙悟空已被如来利用六耳猕猴一战中,安安静静、无人知晓的收服了。也有人说佛祖能通晓过去未来,早就设此考验,算到六耳猕猴必死于孙悟空手上,届时孙悟空就能战胜心魔,真正走上成仙之路。如果佛祖出手阻挡孙悟空的那一棍,保住六耳猕猴性命,那么设此考验又有何意义?这也说明了,孙悟空杀死六耳猕猴,彻底清除了自己内心的邪恶一面,从内心上懂得了成仙成佛的真正的道路。所以在“真假美猴王”一难之后才会服服帖帖,真心为皈依佛门而保护唐僧。

       西游记的故事还在演绎流传,设计模式的精彩稍后继续......