728x90
출처 : 책 - java 언어로 배우는 디자인 패턴 입문
22. Command - 명령을 클래스로 표현하기
1. 목적
- 말 그대로 메소드들의 실행들을 묶어 명령 클래스로 만든다.
- 장점 : 명령을 하나의 물건처럼 표현한다. 명령의 묶음 클래스가 존재하며,
명령 클래스의 수정없이 새로운 명령 클래스2를 추가해 명령을 늘릴 수 있다. ( OCP 부합 )
- 역할
Client - Main 클래스( Invoker의 execute 메소드 호출 )
Invoker - Command 클래스들의 집합
Command - Command 클래스
Receiver - Command 클래스의 명령을 받아 실제로 수행.
2. 예제
(1) MacroCommand - Invoker 역할, Command 클래스들의 집합. 명령 저장의 기능도 구현
package command;
import java.util.Stack;
import java.util.Iterator;
public class MacroCommand implements Command {
// 명령의 집합
private Stack commands = new Stack();
// 실행
public void execute() {
Iterator it = commands.iterator();
while (it.hasNext()) {
((Command)it.next()).execute();
}
}
// 추가
public void append(Command cmd) {
if (cmd != this) {
commands.push(cmd);
}
}
// 최후의 명령을 삭제
public void undo() {
if (!commands.empty()) {
commands.pop();
}
}
// 전부 삭제
public void clear() {
commands.clear();
}
}
(2) Command 인터페이스
package command;
public interface Command {
public abstract void execute();
}
(3) DrawCommand - Command 구현1
package drawer;
import command.Command;
import java.awt.Point;
public class DrawCommand implements Command {
// 그림 그리기 대상
protected Drawable drawable;
// 그림 그리기 위치
private Point position;
// 생성자
public DrawCommand(Drawable drawable, Point position) {
this.drawable = drawable;
this.position = position;
}
// 실행
public void execute() {
drawable.draw(position.x, position.y);
}
}
(4) Drawble 인터페이스 - 편의성을 위해 만든 그리는(Draw) 클래스들의 인터페이스
package drawer;
public interface Drawable {
public abstract void draw(int x, int y);
}
(5) DrawCanvas - Receiver 역할, Command의 명령을 받아 실제로 수행.
package drawer;
import command.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
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) {
setSize(width, height);
setBackground(Color.white);
this.history = history;
}
// 이력 전체를 다시 그리기
public void paint(Graphics g) {
history.execute();
}
// 그림 그리기
public void draw(int x, int y) {
Graphics g = getGraphics();
g.setColor(color);
g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
}
}
(6) Main - Client 역할. Invoker 메소드 호출.
import command.*;
import drawer.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
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 title) {
super(title);
this.addWindowListener(this);
canvas.addMouseMotionListener(this);
clearButton.addActionListener(this);
Box buttonBox = new Box(BoxLayout.X_AXIS);
buttonBox.add(clearButton);
Box mainBox = new Box(BoxLayout.Y_AXIS);
mainBox.add(buttonBox);
mainBox.add(canvas);
getContentPane().add(mainBox);
pack();
show();
}
// ActionListener용
public void actionPerformed(ActionEvent e) {
if (e.getSource() == clearButton) {
history.clear();
canvas.repaint();
}
}
// MouseMotionListener용
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
Command cmd = new DrawCommand(canvas, e.getPoint());
history.append(cmd);
cmd.execute();
}
// WindowListener용
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public static void main(String[] args) {
new Main("Command Pattern Sample");
}
}
728x90
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 낭비 없애기 21. Proxy (0) | 2021.01.17 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 낭비 없애기 20. Flyweight (0) | 2021.01.17 |
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 19. State (0) | 2021.01.17 |
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 18. Memento (0) | 2021.01.15 |
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 17. Observer (0) | 2021.01.14 |
댓글