团队管理者
前面说到我当程序员中介的经历,后来我就有点烦了,这客户有什么需求,都直接指名道姓找这个程序员那个程序员谈需求,我这会儿得给程序员A聊需求,过会儿得给程序员B聊需求,然后又得跟C说,跟D说,那怎么搞,客户不烦我都烦了。 后来,我决定了,我要把自己的权力扩大一点,有什么事儿直接和我说就够了,我去传达客户意思,这样客户也不用一个人面对那么多人,程序员们也可以不用抛头露面,多好。
这个案例中有哪些因素出现了呢? 首先是客户,不断提出需求修改的客户。 然后是我这个给程序员们下达命令的管理者。 接下来是负责UI的程序员A、负责后台的程序员B、负责需求分析的程序员C、D。 客户的需求,从直接传达到各个程序员,转移带传达给团队负责人,我,然后由我来统一调配。
那我们来画一下类图:
但是,仅仅通过一个字符串来传递信息,并不具备约束力,所以我们对类图进行如下修改:
解决方法是:对客户发出的命令进行封装,每个命令是一个对象,避免了客户和负责组员之间的交流误差。 Command抽象类只有一个方法,其作用就是用来执行命令,而项目组长类主要用来将命令解析执行。
其中,Command抽象类是整个扩展的核心。
代码实现
代码语言:javascript复制#include<iostream>
using namespace std;
//需求抽象类
class abstractXQ {
public:
virtual void find() = 0; //找到对应程序员
virtual void add() = 0; //新增任务
virtual void del() = 0; //删除任务
virtual void change() = 0; //修改任务
virtual void show() = 0; //发布代码
};
//UI程序员
class UI :public abstractXQ {
public:
void find() { cout << "找到UI程序员" << endl; }
void add() { cout << "新增UI界面" << endl; }
void del() { cout << "UI界面删除" << endl; }
void change() { cout << "UI界面修改" << endl; }
void show() { cout << "UI代码发布" << endl; }
};
//后端
class BK :public abstractXQ {
public:
void find() { cout << "找到后端程序员" << endl; }
void add() { cout << "新增后端功能" << endl; }
void del() { cout << "后端功能下架" << endl; }
void change() { cout << "后端功能修改" << endl; }
void show() { cout << "后端代码发布" << endl; }
};
//需求
class XQ :public abstractXQ {
public:
void find() { cout << "找到需求分析" << endl; }
void add() { cout << "新增需求" << endl; }
void del() { cout << "需求删减" << endl; }
void change() { cout << "需求修改" << endl; }
void show() { cout << "需求分析发布" << endl; }
};
//任务调度基类
class Command {
protected:
//我想知道,这个保护数据的意义在哪里?
//公有继承的子类不是照样用吗?
UI* ui = new UI();
BK* bk = new BK();
XQ* xq = new XQ();
public:
virtual void execute() = 0;
};
//增加需求
class add_XQ :public Command { //使用保护继承,会导致子类无法转换为父类对象
void execute(){
xq->find();
xq->add();
xq->show();
}
};
//删除界面
class del_UI :public Command {
void execute() {
ui->find();
ui->del();
ui->show();
}
};
//项目组长
class master {
private:
Command* command;
public:
void set_Comment(Command* c) { this->command = c; }
void get_order() { this->command->execute(); }
};
//客户端类
int main()
{
master* m = new master();
Command* c1 = new add_XQ();
Command* c2 = new del_UI();
m->set_Comment(c1);
m->get_order();
m->set_Comment(c2);
m->get_order();
return 0;
}
感悟
怎么说呢?其实这个拓展性说不好他也确实一般般,你看,Command上层,要是加一个类,就得修改Command,要加新命令,又得修改Command下层,两头要修改。 我觉得与其这样,那为啥不考虑一下模板、工厂、建造者,反正都是写死的。
当然,也是有它的闪光点的,不过这些模式相似度也太高了。不好好捋清楚还真不好用。
命令模式
命令模式是个高内聚的模式! 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者纪录请求日志,可以提供命令的撤销和恢复功能。 有兴趣自己去加一下这两个功能,或者去我上一个系列的命令模式里面去找也有。 学以致用,马上用!!
学以致用
命令模式的优点
- 类间解耦 调用者角色和接受者角色之间没有任何依赖关系,调用者实现功能的时候只需要调用Command抽象类的execute方法就可以,不需要了解是哪个接受者在执行。
- 可拓展性 Command
- 命令模式与其他模式结合会更加优秀 命令模式可以结合责任链模式,实现命令模式族解析任务;结合模板方法模式,可以减少command子类膨胀的问题。
命令模式的缺点
Command会膨胀。
用武之地
你觉得哪里能用那就能用。
今天就到这里,请期待:下一篇“责任链模式”