|
COMMAND
このパターンは、要求を出すオブジェクトと処理をするオブジェクトを分離します。
COMMAND パターンは、、Invoker
と Command と Receiver の三つのクラスで構成されています。Invoker
はイベント(メソッド呼び出し)を受けると、イベントに対応する処理を行う Command を生成し、しかるべき手順でを発火させる役割を担います。Command はイベントに応じた処理を手順を記述したものです。スクリプトのようなものと捉えるとわかりやすいと思います。Receiver は、その処理を行う実体です。実際にはOSやミドルウェアが用意するAPIや、ドライバなどがそれにあたると思います。
このパターンは、イベントに対する処理の流れが Command にカプセル化されますので、イベントに対応した手順が非常に分かりやすくなるのが特徴です。組み込みシステムでは非常に有用なパターンです。
具体例を知りたい方は、『COMMAND
でMIDIプレイヤーを作ってみよう』 を参照してください。
■ 『COMMANDの骸骨』の構造

■ 『COMMANDの骸骨』の協調関係

■ 『COMMANDの骸骨』 プログラム・コード
| □ Java2版 |
// Copyright(C) 2000-2003 Yoshinori Oota All rights reserved.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class CommandSample {
static public void main(String[] args) {
Invoker invoker = new Invoker();
invoker.Store(new PrintCommand("Hello Command Pattern."));
invoker.Store(new DialogCommand("This is Command Pattern."));
invoker.Execute();
}
}
class Invoker {
private LinkedList _commandQueue = new LinkedList();
public void Store(Command command) {
_commandQueue.add(command);
}
public void Execute() {
while (_commandQueue.size() != 0) {
Command command = (Command)_commandQueue.removeFirst();
command.Execute();
}
}
}
abstract class Command {
abstract public void Execute();
}
class PrintCommand extends Command {
private String _value = null;
public PrintCommand(String val) {
_value = val;
}
public void Execute() {
System.out.println(_value); // System が Receiver になる。
}
}
class DialogCommand extends Command implements ActionListener {
private String _value = null;
private Frame _frame = new Frame("Command Sample"); // Frame が Reciver.
public DialogCommand(String val) {
_value = val;
}
public void Execute() {
_frame.add("Center", new Label(_value, Label.CENTER));
Button ok = new Button("OK");
ok.addActionListener(this);
_frame.add("South", ok);
_frame.setSize(200, 100);
_frame.show();
}
public void actionPerformed(ActionEvent event) {
_frame.dispose();
System.exit(0);
}
}
|
| ○ C++版 |
// Copyright(C) 2003 Yoshinori Oota All rights reserved.
#include <windows.h>
#include <list>
#include <iostream>
using namespace std;
class Command {
public:
Command();
virtual ~Command();
virtual void Execute() = 0;
};
class PrintCommand : public Command {
public:
PrintCommand(const string& str);
virtual ~PrintCommand();
virtual void Execute();
private:
string value_;
};
class DialogCommand : public Command {
public:
DialogCommand(const string& str);
virtual ~DialogCommand();
virtual void Execute();
private:
string value_;
};
class Invoker {
public:
Invoker();
~Invoker();
void Store(Command* cmd);
void Execute();
private:
list<Command*> commandQueue_;
};
Command::Command() { }
Command::~Command() { }
PrintCommand::PrintCommand(const string& str) : value_(str) { }
PrintCommand::~PrintCommand() { }
void PrintCommand::Execute() {
cout << value_ << endl; // iostream がReceiver
}
DialogCommand::DialogCommand(const string& str) : value_(str) { }
DialogCommand::~DialogCommand() { }
void DialogCommand::Execute() {
// win32 が Receiver.
MessageBox(0, value_.c_str(), "Command Sample", MB_OK|MB_SETFOREGROUND);
}
Invoker::Invoker() { }
Invoker::~Invoker() {
list<Command*>::iterator it = commandQueue_.begin();
while (it != commandQueue_.end()) {
delete (*it);
++it;
}
}
void Invoker::Store(Command* cmd) {
commandQueue_.push_back(cmd);
}
void Invoker::Execute() {
while (!commandQueue_.empty()) {
Command* command = commandQueue_.front();
commandQueue_.pop_front();
command->Execute();
delete command;
}
}
int main() {
Invoker* invoker = new Invoker();
invoker->Store(new PrintCommand("Hello Command Pattern"));
invoker->Store(new DialogCommand("This is Command Pattern"));
invoker->Execute();
delete invoker;
return 0;
}
|
| ○ C版 |
/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
enum COMMAND_TYPE { PRINT ,DIALOG };
/* Command Interface */
struct Command {
char* value_;
void (*Execute)(struct Command* pthis);
};
struct Command* New_Command (enum COMMAND_TYPE type ,char* str);
void Delete_Command(struct Command* command);
void Command_Execute_Print(struct Command* pthis);
void Command_Execute_Dialog(struct Command* pthis);
/* Command Queue Interface */
struct CommandQueue {
struct Command* cmd_;
struct CommandQueue* next_;
};
struct CommandQueue* New_CommandQueue(struct Command* command);
void Delete_CommandQueue(struct CommandQueue* queue);
/* Command Class Implementation */
struct Command* New_Command(enum COMMAND_TYPE type ,char* str) {
struct Command* command = NULL;
char* value = NULL;
command = (struct Command*)malloc(sizeof(struct Command));
value = (char*)malloc(strlen(str)+1);
strcpy(value, str);
command->value_ = value;
switch (type) {
case PRINT:
command->Execute = &Command_Execute_Print;
break;
case DIALOG:
command->Execute = &Command_Execute_Dialog;
break;
}
return command;
}
void Delete_Command(struct Command* command) {
if (command == NULL) {
return;
}
free(command->value_);
command->value_ = NULL;
free(command);
command = NULL;
return;
}
void Command_Execute_Print(struct Command* pthis) {
printf("%s\n" ,pthis->value_);
return;
}
void Command_Execute_Dialog(struct Command* pthis) {
MessageBox(0 ,pthis->value_ ,"Command Sample" ,MB_OK|MB_SETFOREGROUND);
return;
}
/* CommandQueue Implementation */
struct CommandQueue* New_CommandQueue(struct Command* cmd) {
struct CommandQueue* queue = NULL;
queue = (struct CommandQueue*)malloc(sizeof(struct CommandQueue));
queue->command_ = cmd;
queue->next_ = NULL;
return queue;
}
void Delete_CommandQueue(struct CommandQueue* queue) {
if (queue == NULL) {
return;
}
free(queue);
queue = NULL;
return;
}
/* Invoker */
struct CommandQueue* gQueueTop = NULL;
struct CommandQueue* gQueueLast = NULL;
void Invoker_Store(struct Command* cmd) {
struct CommandQueue* queue = NULL;
if (gQueueTop == NULL) {
gQueueTop = New_CommandQueue(cmd);
gQueueLast = gQueueTop;
} else {
gQueueTop = New_CommandQueue(cmd);
gQueueLast->next_ = queue;
gQueueLast = queue;
}
return;
}
void Invoker_Execute() {
struct CommandQueue* cur = NULL;
struct Command* command = NULL;
while (gQueueTop != NULL) {
tmp = gQueueTop->next_;
command = gQueueTop->command_;
command->Execute(command);
Delete_Command(command);
Delete_CommandQueue(gQueueTop);
gQueueTop = tmp;
}
gQueueLast = NULL;
return;
}
void Invoker_Clean() {
struct CommandQueue* cur = NULL;
struct CommandQueue* tmp = NULL;
while (gQueueTop != NULL) {
tmp = gQueueTop->next_;
Delete_Command(gQueueTop->command_);
Delete_CommandQueue(gQueueTop);
gQueueTop = tmp;
}
gQueueLast = NULL;
return;
}
int main() {
Invoker_Store(New_Command(PRINT ,"Hello Command Pattern"));
Invoker_Store(New_Command(DIALOG ,"This is Command Pattern"));
Invoker_Execute();
Invoker_Clean();
return 0;
}
|
|
改訂履歴
|
2005.2.25 |
説明文が意味不明なのを修正さらにデザインパターンの塗り薬へのリンクを追加 |
| |
2009.2.22 |
C言語版を追加 |
| |
|
|
|