command_url.png
这里我们用一个场景来描述:去川湘阁饭店点一份剁椒鱼头和宫保鸡丁。 这里我们把整个关键流程写出来
接下来我们就可以抽象出具体的角色。客户端当然就是我们的用户,调用者就是收银台出单的妹纸,命令就是抄菜单,接受者就是厨师。这样就很清晰了,客户端(用户)不需要知道功能(炒菜)怎么实现或者谁实现,他只需要找调用者(服务员/前台)描述清楚,然后调用者发命令给接受者(厨师),然后接受者执行命令(炒菜)。 这个流程非常的清晰也不会出错。什么样的命令给什么样的接受者执行,比如:剁椒鱼头,就打剁椒鱼头的票,然后指定给会做剁椒鱼头的师傅做。宫保鸡丁就给会做宫保鸡丁的师傅做。这个过程中,命令(小票)包含接受者(师傅)的信息。不同的命令对应不同的接受者。所以这里建立命令和接受者的抽象。
#include<iostream>
using namespace std;
class Chef
{
public:
virtual int cooking(int id)=0;
virtual void printTicketIds()const = 0;
virtual ~Chef() {}
};
#include "Chef.h"
class FishChef :
public Chef
{
int id;
string name;
deque<int> ticketIds;
public:
FishChef(int id, string name);
int cooking(int id);
void printTicketIds()const;
~FishChef();
};
#include "FishChef.h"
FishChef::FishChef(int id, string name)
{
this->id = id;
this->name = name;
}
FishChef::~FishChef()
{
}
void FishChef::printTicketIds()const {
cout << "id为" << this->id << " 姓名为:" << this->name.c_str() << "的厨师需要做的菜";
for (deque<int>::const_iterator it = ticketIds.begin(); it != ticketIds.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int FishChef::cooking(int id) {
if (ticketIds.size() > 3) {
return 1;
}
ticketIds.push_back(id);
return 0;
}
#include<iostream>
#include "Chef.h"
using namespace std;
class Order
{
protected :
Chef* chef;
public:
Order(Chef* chef) {
this->chef = chef;
}
virtual void make()=0;
~Order() {
if (chef != NULL)
delete chef;
}
};
#include "stdafx.h"
#include "ChuangXiangGeOrder.h"
ChuangXiangGeOrder::ChuangXiangGeOrder(Chef * chef, int id):Order(chef)
{
this->id = id;
}
void ChuangXiangGeOrder::make()
{
if (chef == NULL) {
cout << "请先设置厨师" << endl;
}
int res = chef->cooking(id);
}
ChuangXiangGeOrder::~ChuangXiangGeOrder()
{
}
#include<iostream>
#include<vector>
#include<string>
#include"Order.h"
using namespace std;
using namespace std;
class Waiter
{
protected:
Order* order;
public:
Waiter() {}
virtual pair<int,string> setOrder(Order* order)=0;
virtual void execute()=0;
~Waiter() {}
};
#include "stdafx.h"
#include "ChuanXiangGeWaiter.h"
ChuanXiangGeWaiter::ChuanXiangGeWaiter()
{
}
pair<int, string> ChuanXiangGeWaiter::setOrder(Order* order)
{
Waiter::order = order;
return pair<int, string>();
}
void ChuanXiangGeWaiter::execute()
{
if (order == NULL) {
cout << "请先下单" << endl;
}
order->make();
}
ChuanXiangGeWaiter::~ChuanXiangGeWaiter()
{
}
int main()
{
Chef *chef = new FishChef(1, "张厨师");
Order *order = new ChuangXiangGeOrder(chef,1001);
Waiter *waiter = new ChuanXiangGeWaiter();
waiter->setOrder(order);
waiter->execute();
chef->printTicketIds();
Order *order1 = new ChuangXiangGeOrder(chef, 1002);
waiter->setOrder(order1);
waiter->execute();
chef->printTicketIds();
Order *order2 = new ChuangXiangGeOrder(chef, 1003);
waiter->setOrder(order2);
waiter->execute();
chef->printTicketIds();
return 0;
}
结果:
command.png
线程池 Executor就是抽象调用者
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
我们看到其中一个实现类ThreadPoolExecutor
图片来自官方api文档
看到Executor的源码,我们看到参数的起名都是command。这里Runable就是抽象的命令。那接受者呢。其实这里的接受者也是Runable。同时ThreadPoolExecutor除了能够发起命令外,还可以对Runable进行排队。这里我们用一个例子说明
public class TestMain {
public static void main(String[] args) {
new Thread(new TaskA(1)).start();
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new TaskA(2));
executor.execute(new TaskA(3));
executor.execute(new TaskA(4));
}
static class TaskA implements Runnable {
private int id;
public TaskA(int id) {
this.id = id;
}
public void run() {
log(id+" TaskA begin");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log(id+" TaskA end");
}
}
public static void log(String content) {
System.out.println(content);
}
}
结果
1 TaskA begin
2 TaskA begin
3 TaskA begin
1 TaskA end
3 TaskA end
2 TaskA end
4 TaskA begin
4 TaskA end