【转】设计模式学习笔记(13)-职责链

职责链(Chain of Responsibility)模式是我们要讲的第一个行为模式,我们已经学习了创建型模式和结构型模式。创建型模式旨在对对象的创建进行规划,已获得符合要求的对象,结构型模式则是对已有对象或类的组合以获得更多的功能。而今天讲的行为模式则是反映了对象之间的关系,涉及到算法和对象之间职责的分配。

职责链模式说起来很简单,在现实生活中,当我们有事情要反映的时候,我们会找最低级的部门,如班级的事情先向班长反映,班长解决不了再向辅导员反映,辅导员解决不了则向系主任反映。如果系主任解决了这个问题则就不需要向校长反映了。这些人构成了一个职责链,每个人都负责自己该负责的事情,如班长就解决不了调宿舍的问题,而系主任也不会管谁谁谁没交作业的问题。这样一来大家各司其职,职责明确了。

这是现实生活中的一个例子,在程序设计中,所谓的职责链是指,当客户程序发出一个请求时,它并不知道它的请求会不会被处理以及被谁处理。而处理者也不会管这个请求是谁发布的或者是谁转交给自己的,它只管处理或是不处理,不处理的话是转交给下一个处理程序还是直接丢弃掉。表面上看了这种模式使得各对象对别的程序情况知之甚少,甚至是毫无所知,但这正式我们要达到的效果,那就是解耦(decouple)。我不了解你,那我就不依赖你,所以无论你是好是坏对我都没有影响。这便是职责链模式所要达到的效果。

从总体上来看,职责链模式的类图应该是这样的:

从类图上来看,客户请求IHandler处理自己的请求,Ihandler是所有职责链上对象的父类,它有一个对另一个Handler的引用,它的handle方法如果能处理客户请求则处理,否则转交给下一个Handler,呈现一个链状结构,所以称之为职责链。

我们来写一个简单的Demo:

定义请求的类型

1
typedef enum {READ, WRITE, EXECUTE, UNKNOWN} Type;

定义Handler接口和实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class IHandler
{
protected:
    IHandler* _handler;
    IHandler(IHandler* handler) : _handler(handler){}
public:
    virtual void handle(Type arg){}
};
class IReadHander : public IHandler
{
public:
    IReadHander(IHandler* handler) : IHandler(handler){}
    void handle(Type arg)
    {
        if(arg == READ)
        {
            cout << "This Request is handled by IReadHander" << endl;
        }
        else
        {
            if(IHandler::_handler != 0)
                IHandler::_handler->handle(arg);
        }
    }
};
class IWriteHander : public IHandler
{
public:
    IWriteHander(IHandler* handler) : IHandler(handler){}
    void handle(Type arg)
    {
        if(arg == WRITE)
        {
            cout << "This Request is handled by IWriteHander" << endl;
        }
        else
        {
            if(IHandler::_handler != 0)
                IHandler::_handler->handle(arg);
        }
    }
};
class IExecHander : public IHandler
{
public:
    IExecHander(IHandler* handler) : IHandler(handler){}
    void handle(Type arg)
    {
        if(arg == EXECUTE)
        {
            cout << "This Request is handled by IExecHander" << endl;
        }
        else
        {
            if(IHandler::_handler != 0)
                IHandler::_handler->handle(arg);
        }
    }
};

主方法里这样写

1
2
3
4
5
IHandler* readHandler = new IReadHander(0);
IHandler* writeHandler = new IWriteHander(readHandler);
IHandler* execHandler = new IExecHander(writeHandler);
execHandler->handle(READ);
return 0;

 

这个程序里构建了一个从IExecHandler -> IWriteHandler -> IReadHandler的职责链。当客户端请求一个READ的请求时,该请求被IReadHandler处理,结果如下:

1
This Request is handled by IReadHander

 

当客户端请求一个UNKNOWN请求时,由于职责链中没有处理该请求的对象,这个请求被忽略掉了。
从我们的主方法里可以看到,职责链的使用十分类似于Decorator模式,但是职责链中的对象是平等的,甚至不同的链之间是可以交叉的。当客户请求达到时,顺着链网上梳理直至找到处理对象或者到达结尾被抛弃掉。

最后我们来看看职责链模式的适用性:

  • 有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定
  • 想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求
  • 可处理一个请求的对象集合应被动态指定

职责链模式主要应用在GUI事件处理上,由于事件处理是冒泡形式的,一个Button放在一个Panel上,如果Button不能处理该请求就应转交给其父类,由其父类处理。这十分符合职责链模式的处理方法。

 

 

转自:http://lecoding.com/articles/224.html

posted on 2013-03-05 16:00  TheKingOfKingFish  阅读(178)  评论(0)    收藏  举报

导航