六、命令模式 责任链模式

命令模式

面向对象中,一实例化一个对象,然后填充该对象。再由别的对象调用该对象。
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。单个请求封装成对象以后,我们就可以对这个请求存储更多的信息,使请求拥有更多的能力。

将请求封装为对象,那么可以不必为用户的每一次提交请求都去执行,只要当前客户已经提交过请求,那么就忽略或提示消息给用户。
同时用户可以撤销请求(或者可不可以更改请求内容?)
然后服务器将请求排队,然后处理。

实现

那12306网站来说。
命令可能有很多种,比如订票命令,退票命令,改签命令等等,等等乱七八糟的。
如果能一起接收这些命令,那么就需要一个抽象层,命令继承一个基类。这样接收这个基类的指针就可以了。
所以命令类应该有两个。

UML

命令类

封装请求和处理请求的对象。并不直接去处理这些请求。
所以他实际的成员函数都可以的protect,因为这些对象的成员函数都是有提交这些请求的对象来处理。
这些类都应该持有一个处理这些请求的对象,所以我们在基类中指定有这么一个私有成员,在初始化的时候填充。
然后每一个具体的命令类,都应该有自己的一些数据成员,比如订票的时候用户信息,票的信息等,我们存储在Data这个集合,或者我们自己假设的一个类型中。

//抽象层
class Commend
{
public:
  virtual void doit()=0;
};

//具体的命令类
class OrderCom:public Commend
{
public:
  OrderCom(Hander *);
  vitrual void doit()
  {
    hander->exc();
  }
private:
  Data data;
  Handler *handler;
};

class RefundCom:public Commend
{
//实现,同上
private:
  Handler *handler;
};

命令类与具体执行命令的类,应该应该解耦。也就是在做中间层。
这个中间层应不应该也是个虚类,然后具体的子类再执行对应的命令?
这个就要示情况而定了。

因为这里已经实现了解耦,如果对一个请求处理的对象可以有多个,那么就有必要做一个抽象层。

handle类执行具体处理任务。

class Handle
{

}

为了实现请求的排队和集中处理,我们还需要在做一个对象。用来集中管理这些命令子类。
说白了,这些命令子类,只是在封装需要处理的对象,和处理者。它们他们并不进行实际的处理。
这个类,可以继承Commend也可以不继承,这个类持有一个容器他存储这些Commend,继承的原因是:这个队列类也有一个函数成员exc()用来执行容器里面Commend

class Exc
{
public:
  void exc();//挨个执行队列里的命令
  void add();
  void remove();
private:
  vector<Commend *> _list;
};

除去析构,在移除Commend时要一个个遍历,如果多的话,那就很麻烦了。

责任链模式

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

简单来讲,就是可以将一个对象(或者是命令模式中的一个请求),传递给一条“链”,直到链中的某个处理该请求的对象,处理了个对象,那么就返回。

实现

现象一下,可以这样做:

能够传递

  1. 要是这个请求可以在一条链中传递,那么能想到的方法,就是将处理这个请求的对象做一个抽象层,然后每个实际的处理类继承这个抽象层。然后一个储存这个“链”的类,拥有一个容器,按照顺序存储处理类的对象。
    2.节省一个“链”类,想list一样(单向链表),将下一个处理对象存储在本对象中,如果本对象不能处理该对象,那么就调用下一个处理对象的处理函数。

确保一定能够被处理

调用处理类的成员函数,先判断是否能够处理该对象,如果不能,那就。。。跳。。。
也可以在条之前判断一下_next如果是一个nullptr那么就返回false。这样的话,可以不用使用终端的那个类。

  1. 采用第一种容器的方式,那么就遍历对象,依次调用。如果能够处理就break。同时,在开始处理之前,可以确保容器的尾元素一定能够和醋里该对象。
  2. 采用第二种“单向链表”方式,那么需要确保最后一个处理类的成员函数一定能够处理该请求,或者就返回一个不能处理。

请求需要存储在处理类中嘛?

采用处理类调用函数成员直接处理请求,那么请求可以不用存储。

如何添加下一个处理类

可以直接采用函数成员addNext()的方式。
也可以采用直接在构造函数中初始化。

最后,选取的是“单向链表”的方式。

UML

代码

//处理类的基类
class AbHandler
{
public:
  virtual bool exc(Req * req)=0;
private:
  AbHandler *_next;
};


//处理类,根据信息判断是否可以执行。
class Exc1Handler:AbHandler
{
public:
  Exc1Handler(AbHandler* handler):_next(handler);
  virtual bool exc(Req * req)
  {
    if(/*判断req信息和本类的其他数据成员是否能够处理该请求*/)
    {
      //do
      return true;
    }
    return _next->exc(req);
  }
};

//链的终端,确保一定可以执行。
class EndHandler:Abhandler
{
//其他不变,构造函数传入参数为空
public:
  virtual bool exc()
  {
    //提示信息
    return false;
  }
};

使用

int main()
{
  EndHandler *endHandler=new EndHandler;
  Exc1Handler *exc1=new Exc1Handler(endHandler);
  //.....添加其他的。
  Exc9Handler *exc9=new Exc9Handler(exc8);
  //另外一个请求类。。。
  Req req;
  exc9->exc(req);
   
}

链的终端先创建,然后执行的是链的开头。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,820评论 1 15
  • 1 场景问题# 1.1 申请聚餐费用## 来考虑这样一个功能:申请聚餐费用的管理。 很多公司都有这样的福利,就是项...
    七寸知架构阅读 2,985评论 3 58
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,574评论 25 707
  • 很久了,一直酝酿着写自己的故事。但是,等我读了很多别人的故事,尤其最近真实的发生在自己身边的事情以后,发现其...
    唠叨妹妹阅读 471评论 0 1