天天看点

大话设计模式:职责链模式

一、什么是职责链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.
           

将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.当客户提交一个请求时,请求是沿链传递直至有一个职责负责处理它.职责单一不彼依赖,处理完并自动转移.职责模式每个单链不必知道下一个链是谁,这些由环境设定.

UML图
           
大话设计模式:职责链模式

Handler: 操作类,设置下一个职责的方法,和一个当前处理职责的抽象方法.

ConcreteHandlerA:具体操作类A,现实具体当前职责

Client:环境类,负责给定职责链条

二、适用场景

职责模块链接并不固定,可以灵活调整的情况.

在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。可动态指定一组对象处理请求。比如击鼓传花,一个选手处理完之后交给下一位.

三、优缺点

优点

降低耦合度,请求与接收耦合度降低

接收职责之间解耦合,只需关注自身的部分,不属自身部分的内容交给下一个职责链,并不必关心是谁.

可灵活调整职责链的布局,增加替换或删除都很方便.

缺点

不能保证请求一定被接收.

系统性能的繁复度增加,调试时不太方便,可能会造成循环调用.

不容易观察运行时的特征,有碍于除错.

四、大话中的例子

公司管理人员处理员工请求, 经理/总监/总经理分别的处理权限是不一样的. 大家都继承一个管理者类, 这个类里面做两件事,①设置下一个链接者,②规定处理方案抽象方法. 这些管理者都继承与它,实现抽象方法,依照自己的职责处理.

环境类里面实例不同的管理者,然后给管理者设置职责链条.最后发送请求.

五、我的例子

using System;


namespace ChainOfResposMode
{
    class Program
    {
        static void Main(string[] args)
        {

            Ninja ninja1 = new Crew();
            Ninja ninja2 = new Captain();
            Ninja ninja3 = new Leader();
            ninja1.SetSuperior(ninja2);
            ninja2.SetSuperior(ninja3);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(1);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(3);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(7);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(10);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(500);
        }
    }

    abstract class Ninja
    {
        string name;

        protected Ninja ninja;

        public string Name { get => name; set => name = value; }

        public void SetSuperior(Ninja ninja)
        {
            this.ninja = ninja;
        }
        public abstract void FindEnemy(int enemynum);
    }

    class Crew : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 2)
            {
                Console.WriteLine("{1},对面只有{0}人,干掉他", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{0},人太多,我拿不定主意", GetType().Name);
                ninja.FindEnemy(enemynum);
            }
        }
    }

    class Captain : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 5)
            {
                Console.WriteLine("{1},对面有{0}人,配合好,一起上", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{0},人太多,我拿不定主意", GetType().Name);
                ninja.FindEnemy(enemynum);
            }
        }
    }

    class Leader : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 30)
            {
                Console.WriteLine("{1},对面有{0}人,我们做好战略部署全歼敌人", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{1},对面有{0}人,拼死守护村子", enemynum, this.GetType().Name);
            }
        }
    }
}

           
运行结果
           
大话设计模式:职责链模式

PS:职责链模式和 状态模式有些类似,不过两者还是有很大区别,状态模式的状态过渡是在编译时就已经确定了,不同状态之间的转换,但是职责链模式的职责转换是在环境中给定的,也可以修改替换,显得更灵活。