設計模式(Java)—Command模式
阿新 • • 發佈:2018-12-12
一個類在進行工作時會呼叫自己或是其他類的方法,雖然呼叫結果會反映在物件的狀態中,但是並不會留下工作的歷史紀錄。 這時,如果有一個類,用來表示進行這項工作的命令就會方便很多。每一項想做的工作就不再是方法的呼叫這種動態處理了,而是一個表示命令的類的例項,既可以用物來表示,要想管理工作的歷史紀錄,只需管理這些例項的集合即可,而且還可以隨時再次執行過去的命令,或是將多個過去的命令整合為一個新命令並執行。 在設計模式中,我們稱這樣的命令為Command模式。
示例程式 這段示例程式是一個畫圖軟體,使用者拖動滑鼠時程式會繪製出紅色圓點,點選clear按鈕後會清除所有圓點。 使用者每拖動一次滑鼠,應用程式都會為“在這個位置畫一個點”這條命令生成一個DrawCommand類的例項,只要儲存了這條例項,以後有需要時就可以重新繪製。
Command介面 該介面是表示命令的介面,它的作用就是執行什麼東西。
package Command;
//命令介面
public interface Command {
//宣告抽象方法
public abstract void execute();
}
MacroCommand類 該類表示由多條命令整個成的命令,該類實現了Command介面。
package Command; import java.util.Iterator; import java.util.Stack; //實現Command介面,組織多條命令 public class MacroCommand implements Command { private Stack<Command> commands = new Stack(); //執行壓入命令棧中的每條命令,通過迭代器呼叫執行方法 @Override public void execute() { // TODO Auto-generated method stub Iterator iterator = commands.iterator(); while(iterator.hasNext()){ ((Command)iterator.next()).execute(); } } //如果有了新的命令,將新的命令壓入棧中 public void append(Command cmd){ if(cmd!=this){ commands.push(cmd); } } //如果撤回命令,則將命令物件pop出棧 public void undo(){ if(!commands.empty()){ commands.pop(); } } //棧清空 public void clear(){ commands.clear(); } }
DrawCommand類 該類表示繪製一個點的命令,該類的兩個欄位一個儲存的是繪製物件,另外一個儲存的是繪製位置。
package Command; import java.awt.Point; //執行一條命令的類 public class DrawCommand implements Command { //建構函式需要具體繪畫類的例項和該物件在畫布上的位置 protected Drawable drawable; private Point position; public DrawCommand(Drawable drawable,Point position) { // TODO Auto-generated constructor stub this.drawable = drawable; this.position = position; } //執行繪製一個點的方法 @Override public void execute() { // TODO Auto-generated method stub drawable.draw(position.x,position.y); } }
Drawable介面 該介面是表示繪製物件的介面。
package Command;
//繪製的介面
public interface Drawable {
public abstract void draw(int x,int y);
}
DrawCanvas類 該類實現了Drawable介面。
package Command;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
//繪製畫布和繪製點的類
public class DrawCanvas extends Canvas implements Drawable {
private Color color = Color.red;
private int radius = 6;
private MacroCommand history;
//建構函式繪製畫布
public DrawCanvas(int width,int height,MacroCommand history) {
// TODO Auto-generated constructor stub
setSize(width,height);
setBackground(Color.white);
this.history = history;
}
//該方法繪製一個點,包括建立畫筆例項,設定畫筆顏色,以及最終的畫圓
@Override
public void draw(int x, int y) {
// TODO Auto-generated method stub
Graphics graphics = getGraphics();
graphics.setColor(color);
graphics.fillOval(x-radius, y-radius, radius*2, radius*2);
}
//重新執行命令棧中的命令
public void paint(Graphics g){
history.execute();
}
}
Main類
package Command;
import java.awt.Canvas;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main extends JFrame implements ActionListener, MouseMotionListener, WindowListener {
//建立多命令鏈物件
private MacroCommand history = new MacroCommand();
//初始化畫布
private DrawCanvas canvas = new DrawCanvas(400, 400, history);
//建立按鈕物件
private JButton clearButton = new JButton("clear");
public Main(String string){
super(string);
//為空間新增事件監聽
this.addWindowListener(this);
canvas.addMouseMotionListener(this);
clearButton.addActionListener(this);
//設定佈局
Box buttonnBox = new Box(BoxLayout.X_AXIS);
buttonnBox.add(clearButton);
Box mainBox = new Box(BoxLayout.Y_AXIS);
mainBox.add(buttonnBox);
mainBox.add(canvas);
getContentPane().add(mainBox);
pack();
show();
}
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
//滑鼠拖拽事件發生時,建立一條命令,將該命令加入棧中,執行命令
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
Command cmd = new DrawCommand(canvas,e.getPoint());
history.append(cmd);
cmd.execute();
}
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//如果按下清除鍵,則清除歷史棧中的命令,重新繪製畫布
if(e.getSource() == clearButton){
history.clear();
canvas.repaint();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Main("Command Pattern Sample");
}
}
Command模式類圖 Command模式時序圖