1.首先什么是命令模式
将一个请求封装成对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。(设计模式之禅)
2.命令模式应该都有哪些属性
1.Receiver命令接收者
2.command命令,
3.invoker执行者
3.实践
3.1餐厅的点菜系统,顾客点菜便是一条命令,服务员为接收者,并将命令传递到厨师处,让厨师执行。餐厅并不只是只有一个菜品,故而应该每个菜品都是一条命令,而服务员手上的单应该是一个命令的集合,也实现命令接口,拥有可执行的属性。
3.2类图设计
3.2编码实现
//命令接口
import com.design.cookApi.CookApi;
public interface Command {
public void execute();
public void setCookApi(CookApi cookApi);
public int getTableNum();
}
//具体命令实现
public class DuckCommand implements Command {
//桌号
private int tableNum;
//持有做菜厨师的引用
private CookApi cookApi = null;
public DuckCommand(int num) {
// TODO Auto-generated constructor stub
this.tableNum = num;
}
public int getTableNum() {
return tableNum;
}
public void execute() {
this.cookApi.cook(tableNum, "北京烤鸭");
}
@Override
public void setCookApi(CookApi cookApi) {
this.cookApi = cookApi;
}
}
//服务员的菜单,命令的集合
public class MenuCommand implements Command {
//记录多条菜品
public Collection<Command> col = new ArrayList<Command>();
public void addCommand(Command cmd) {
col.add(cmd);
}
public int getTableNum() {
return 0;
}
public Collection<Command> getCommands() {
return this.col;
}
public void execute() {
//传递到命令队列,厨师在这里取出命令执行
CommandQueue.addMenu(this);
}
@Override
public void setCookApi(CookApi cookApi) {
}
}
//命令接收者
public class Waiter {
private MenuCommand menuCommand = new MenuCommand();
public void orderDish(Command cmd) {
menuCommand.addCommand(cmd);
}
public void orderOver() {
this.menuCommand.execute();
}
}
//厨师 命令执行者
//多个厨师炒菜,应该是并发的
public class HotCook implements CookApi,Runnable{
public String name;
public HotCook(String name)
{
this.name = name;
}
public void cook(int tableNum, String name) {
int cookTime = (int)(20 * Math.random());
System.out.println(this.name+"厨师正在为"+tableNum+"号桌做"+name);
try
{
Thread.sleep(cookTime);
}catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println(this.name+"厨师为"+tableNum+"号桌做好了:"+name+",共耗时:"+cookTime);
}
public void run() {
while(true)
{
Command cmd = CommandQueue.getOneCommand();
if(null != cmd)
{
cmd.setCookApi(this);
cmd.execute();
}
try
{
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//厨师接口
public interface CookApi {
public void cook(int tableNum, String name);
}
//命令队列
public class CommandQueue {
//用来存储命令对象的队列
private static List<Command> cmds = new ArrayList<Command>();
public synchronized static void addMenu(MenuCommand menu) {
for (Command item : menu.getCommands()) {
cmds.add(item);
}
}
public synchronized static Command getOneCommand() {
Command cmd = null;
if(cmds.size()>0)
{
cmd = cmds.get(0);
cmds.remove(0);
}
return cmd;
}
}