您的位置:首页 > 编程语言 > C#

设计模式 之 职责链

2014-09-21 23:35 183 查看

职责链模式(Chain of Responsibility)

         使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

请假条件:

1.专业课第一
    如果专业课和提高班的课程冲突(包括考试),可以直接和各期纪委负责人请假。(每天上课,由纪委负责人查考勤)
2.百善孝为先
    父母生病、亲属故亡需要回家,可以向米老师请假,并告知纪委;如果非父母生病,需要照顾、料理,超过10天,可以向米老师请假,并告知纪委。
3.身体是革命本钱
    自己生病可以请假,半天之内可以由各期纪委负责人批准,超过半天应该向老师请假,并告知纪委。
4.急事请假
    在规定范围内(三小时之内),直接跟各期纪委负责人请假;三小时以上或规定范围外,需要跟老师请假,之后再和各期纪委负责人打招呼。其他,由纪委负责人决定,如果纪委负责人不能决定的,交于老师决定。

以上是我们提高班的请假条例,有了这个条例,我们就知道如果有一天我们需要请假,有没有满足请假条件,该向谁请假!下面让我们看看代码实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chain_of_Responsibility
{
class Program
{
//学生接口
public interface IStudent{
//获得学生请假级别:级别0:3小时内(纪委直接处理),级别1:超过3小时(由老师处理)
int getLevel();
//获得学生请假消息
string getRequestMessage();
}
//学生实现类
public class Student :IStudent {
//请假级别
private int level=-1;
//请假消息
private string message;

public Student(int level, String message)
{
this.level = level;
this.message=message;
}

public int getLevel()
{
return this.level;
}

public string getRequestMessage(){
return this.message;
}
}
//抽象处理者接口
public interface IHandler
{
//处理请求
void handleRequest(IStudent student);

//设置下一个处理着
void setHandler(IHandler handler);

}
//抽象处理者
public abstract class AbstractHandler : IHandler
{
//下一个处理者
private IHandler handler;

//请假级别
private int level = -1;

//设置级别
public AbstractHandler(int level)
{
this.level = level;
}
//处理请求,交由子类负责进行具体的处理
public abstract void process(IStudent student);

public void handleRequest(IStudent student)
{
if (student != null)
{
if (this.level == student.getLevel())
{
//如果请假级别和当前级别一致,则当前对象进行处理
this.process(student);
}
else
{
if (this.handler != null)
{
Console.WriteLine(student.getRequestMessage() + " 请求米老师处理!");
//如果当前对象处理不了,则交给下一个处理者进行处理
this.handler.handleRequest(student);
}
}
}
}
//设置下一个处理者
public void setHandler(IHandler handler)
{
this.handler = handler;
}
}

//纪委
public class DisciplineHandler : AbstractHandler
{
public DisciplineHandler():base(0){}

public override  void process(IStudent student)
{
Console.WriteLine("纪委 批复:" + student.getRequestMessage ());
}

}
//老师
public class TeacherHandler : AbstractHandler
{
public TeacherHandler() : base(1) { }

public override  void process(IStudent student)
{
Console.WriteLine("老师 批复:" + student.getRequestMessage());
}
}

//设置职责链关联
public class ProcessHandler
{
private IHandler disciplineHandler;
private IHandler teacherHandler;

//单例模式
private static ProcessHandler processHandler = new ProcessHandler();

private ProcessHandler()
{
this.disciplineHandler = new DisciplineHandler();
this.teacherHandler = new TeacherHandler();

this.disciplineHandler.setHandler(this.teacherHandler);
}

public static ProcessHandler getInstance()
{
return processHandler;
}

//发送请假请求
public void sendMessage(IStudent student)
{
this.disciplineHandler.handleRequest(student);
}
}

static void Main(string[] args)
{
ProcessHandler processHandler = ProcessHandler.getInstance();

IStudent student0 = new Student(0, "学生张XX快递到了,要请假20分钟!");
IStudent student1 = new Student(1, "学生李XX运动时摔伤了腿,要请假一周!");
Console.WriteLine("************************************************************");
processHandler.sendMessage(student0);
Console.WriteLine("************************************************************");
processHandler.sendMessage(student1);
Console.WriteLine("************************************************************");
}
}
}




类图:

          


职责链模式包含如下几个角色:
    Handler(抽象处理者):定义一个处理请求的接口。一般设计为抽象类,如果需要,抽象类可以定义出一个方法,以设定和返回下家的引用,通过该引用,处理者可以连成一条链。
    ConcreteHandler(具体处理者):具体处理者接收到请求后,可以选择将请求处理掉,或者将请求传给下家。由于处理者持有下家引用,因此,如果需要,具体处理者可以访问下家。

主要优点:

    1.一个对象无须知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,降低了系统的耦合度。
    2.请求处理对象仅需维持一个指向其后继者的引用,可简化对象的相互连接。
    3.在给对象分派职责时,职责链可以给我们更多的灵活性。

      

主要缺点:

    1.一个请求也可能因职责链没有被正确配置而得不到处理。
    2.对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响。

 

适用场景:

    1.有多个对象处理同一个请求,具体由哪一个来处理还不确定,只有在运行时才能确定哪个对象处理的情况。
    2.消息具有多个接收者,而接收对象又是不明确的情况。只需要向其中的一个对象发出消息,由其内部具体处理。
    3.同一个消息的多个处理对象可能会动态增加或者减少,需要动态地指定的情况。

相关模式:

    1.外观:在设置职责链时,可能会用到外观,让客户端只与外观打交道。
    2.命令:设计了请求传递的行为,请求的传递就用到了命令模式。
    3.观察者:事件触发,将消息发送出去,信息接收者可以同时存在多个。
    4.职责链时按照既定规则进行一系列的消息处理,并且只有一个接收者接收消息进行传递。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# 设计模式