命令模式與合成模式並用實現宏命令功能例述

来源:互联网 发布:dnf驱魔技能改版数据 编辑:程序博客网 时间:2024/06/05 10:11

命令模式將請求一個操作的對象與執行這個操作的對象解耦,使其獨立的演化;命令模式允許系統使用不同的請求把客戶端參數化、允許對請求排隊或者記錄日誌;命令模式與備忘錄模式合用可用來提供命令的恢復和撤銷功能。
-----------------------------------------------------------------------------------
本文將以一個例子來講述命令模式與合成模式的使用實現宏命令功能。
背景:
置機器人於某地,其地方正,經緯之,標其左上角:0,0;命令凡三,'L':左旋90度;'R':左旋90度;'M' 進一。
初態:(x,y),向北
令其'M',則終態:(x,y+1),向北

-----------------------------------------------------------------------------------

靜態類圖:

圖一:機器人靜態類圖

該設計即命令模式與合成模式並用以實現宏命令功能,該類型與本博文《命令模式例述》中類圖相比較,會發現只是增加了一個MacroCommand接口,該接口繼承了命令模式中的Command角色(即RoversCommand接口),使得命令模式中的Invoker角色(即MacroRoversCommand類)可以將其自身看作一個命令來處理。命令模式的Invoker角色亦可實現宏命令功能,此種設計參考合成模式加以擴展,使得合成模式的樹形結構讓宏命令功能更加完美。

為節省篇幅,現列舉Postion類及MacroRoversCommand類關鍵代碼如下:

public class Position {
private Point point;
private HEADING heading;
private Point maxPoint;
public Position(int x,int y,HEADING heading){
this.point = new Point(x,y);
this.heading = heading;
this.maxPoint = new Point(x, y);
}
...
/**
* Spin 90 degrees according to its heading.
* @param direction
*/
public void spin(DIRECTION direction){
if(direction == DIRECTION.LEFT){
switch(heading){
case NORTH:
this.heading = HEADING.WEST;
break;
case EAST:
this.heading = HEADING.NORTH;
break;
case SOUTH:
this.heading = HEADING.EAST;
break;
case WEST:
this.heading = HEADING.SOUTH;
}
}
else {
switch(heading){
case NORTH:
this.heading = HEADING.EAST;
break;
case EAST:
this.heading = HEADING.SOUTH;
break;
case SOUTH:
this.heading = HEADING.WEST;
break;
case WEST:
this.heading = HEADING.NORTH;
}
}
}
/**
* Move a step according to its heading.
*/
public void move(){
switch(heading){
case NORTH:
if(this.point.getY()<this.maxPoint.getY()){
this.point.setY(this.point.getY() + 1);
}
break;
case SOUTH:
if(this.point.getY()>0){
this.point.setY(this.point.getY() - 1);
}
break;
case WEST:
if(this.point.getX()>0){
this.point.setX(this.point.getX() - 1);
}
break;
case EAST:
if(this.point.getX()<this.maxPoint.getX()){
this.point.setX(this.point.getX() + 1);
}
}
}
}

public class MacroRoversCommand implements MacroCommand {
private List<RoversCommand> cmdList = new ArrayList<RoversCommand>();
@Override
public void execute() {
for(RoversCommand roverCmd:cmdList){
roverCmd.execute();
}
}


@Override
public void addCommand(RoversCommand roversCmd) {
cmdList.add(roversCmd);
}


@Override
public void removeCommand(RoversCommand roversCmd) {
cmdList.remove(roversCmd);
}


}