Commandパターンとはデザインパターンの一種で、1つ1つのコマンド(命令)をそのままオブジェクトとして表現するパターンです。
コマンドをオブジェクトとして表現することで、コマンドの管理(追加・削除・実行)が可能になるというメリットがあります。
今回は、ファイルやフォルダを作成するコマンドを管理するサンプルコードを作成してみました。
Commandクラスが1つ1つのコマンドを表し、コマンドの管理はInvokerクラスで行い、コマンドの実際の処理はReceiverクラスで記述します。
【サンプルコード】
・Command.java
// コマンドの抽象クラス
public abstract class Command {
protected String nameOfFileFolder;
protected Receiver receiver;
// コンストラクタ:生成するファイル名・フォルダ名をセット
public Command(String nameOfFileFolder) {
this.nameOfFileFolder = nameOfFileFolder;
}
// コマンドの受け手をセット
public void setReceiver(Receiver receiver) {
this.receiver = receiver;
}
// コマンドの受け手に処理を依頼
public abstract void execute();
}
・ConcreteCommandForOperation.java
// 運用で使用するフォルダ・ファイル作成を指示するクラス
public class ConcreteCommandForOperation extends Command {
public ConcreteCommandForOperation(String nameOfFileFolder) {
super(nameOfFileFolder);
}
public void execute() {
receiver.action
("C:\\pleiades\\workspace\\Hello\\conf\\" + nameOfFileFolder);
}
}
・ConcreteCommandForTemporary.java
// 一時フォルダ・ファイル作成を指示するクラス
public class ConcreteCommandForTemporary extends Command {
public ConcreteCommandForTemporary(String nameOfFileFolder) {
super(nameOfFileFolder);
}
public void execute() {
receiver.action
("C:\\tmp\\" + nameOfFileFolder);
}
}
・Receiver.java
// コマンドの受け手の抽象クラス
public interface Receiver {
// 処理実行
public abstract void action(String path);
}
・ConcreteReceiverMkfil.java
import java.io.File;
import java.io.IOException;
// ファイル作成を行うReceiver
public class ConcreteReceiverMkfil implements Receiver {
public void action(String path) {
File file = new File(path + ".txt");
try {
if (file.createNewFile()){
}else{
System.out.println(path + "作成に失敗しました。");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
・ConcreteReceiverMkdir.java
import java.io.File;
// フォルダ作成を行うReceiver
public class ConcreteReceiverMkdir implements Receiver {
public void action(String path) {
File file = new File(path);
if (file.mkdir()){
}else{
System.out.println(path + "作成に失敗しました。");
}
}
}
・Invoker.java
import java.util.Iterator;
import java.util.Stack;
// コマンドの追加・取消・実行を管理するクラス
public class Invoker {
private Stack<Command> commandStack = new Stack<Command>();
// コマンドを追加する
public void addCommnad(Command command) {
commandStack.push(command);
System.out.println
(commandStack.size() + "個目のコマンドを登録しました。");
}
// 直近のコマンドを削除する
public void undoCommnad() {
if(commandStack.empty()) {
System.out.println("削除するコマンドがありません。");
} else {
commandStack.pop();
System.out.println
( (commandStack.size()+1) + "個目のコマンドを削除しました。");
}
}
// コマンドを順番に実行する
public void execute() {
System.out.println
(commandStack.size() + "個のコマンドを実行します。");
Iterator<Command> itetator = commandStack.iterator();
while (itetator.hasNext()) {
itetator.next().execute();
}
System.out.println("コマンドを実行しました。");
}
}
・CommandMain.java
// メインクラス
public class CommandMain {
public static void main(String[] args) {
// 初期処理
Receiver receiverMkfil = new ConcreteReceiverMkfil();
Receiver receiverMkdir = new ConcreteReceiverMkdir();
Invoker invoker = new Invoker();
// コマンドの作成(5個)
System.out.println("Aファイルを作成するコマンドを登録します。");
Command commandA = new ConcreteCommandForOperation("A");
commandA.setReceiver(receiverMkfil);
invoker.addCommnad(commandA);
System.out.println("Bフォルダを作成するコマンドを登録します。");
Command commandB = new ConcreteCommandForOperation("B");
commandB.setReceiver(receiverMkdir);
invoker.addCommnad(commandB);
System.out.println("C一時ファイルを作成するコマンドを登録します。");
Command commandC = new ConcreteCommandForTemporary("C");
commandC.setReceiver(receiverMkfil);
invoker.addCommnad(commandC);
System.out.println("D一時フォルダを作成するコマンドを登録します。");
Command commandD = new ConcreteCommandForTemporary("D");
commandD.setReceiver(receiverMkdir);
invoker.addCommnad(commandD);
System.out.println("Eファイルを作成するコマンドを登録します。");
Command commandE = new ConcreteCommandForOperation("E");
commandE.setReceiver(receiverMkfil);
invoker.addCommnad(commandE);
// 直近のコマンドの削除
invoker.undoCommnad();
// コマンドの実行
invoker.execute();
}
}
【実行結果】
・コンソール出力
Aファイルを作成するコマンドを登録します。
1個目のコマンドを登録しました。
Bフォルダを作成するコマンドを登録します。
2個目のコマンドを登録しました。
C一時ファイルを作成するコマンドを登録します。
3個目のコマンドを登録しました。
D一時フォルダを作成するコマンドを登録します。
4個目のコマンドを登録しました。
Eファイルを作成するコマンドを登録します。
5個目のコマンドを登録しました。
5個目のコマンドを削除しました。
4個のコマンドを実行します。
コマンドを実行しました。
・ファイルやフォルダの生成確認
C:\pleiades\workspace\Hello\conf>cd C:\pleiades\workspace\Hello\conf
C:\pleiades\workspace\Hello\conf>dir
ドライブ C のボリューム ラベルは です
ボリューム シリアル番号は です
C:\pleiades\workspace\Hello\conf のディレクトリ
2020/02/08 10:02 <DIR> .
2020/02/08 10:02 <DIR> ..
2020/02/08 10:02 0 A.txt
2020/02/08 10:02 <DIR> B
1 個のファイル 0 バイト
3 個のディレクトリ 19,379,642,368 バイトの空き領域
C:\pleiades\workspace\Hello\conf>
C:\pleiades\workspace\Hello\conf>cd C:\tmp\
C:\tmp>dir
ドライブ C のボリューム ラベルは です
ボリューム シリアル番号は です
C:\tmp のディレクトリ
2020/02/08 10:02 <DIR> .
2020/02/08 10:02 <DIR> ..
2020/02/08 10:02 0 C.txt
2020/02/08 10:02 <DIR> D
1 個のファイル 0 バイト
3 個のディレクトリ 19,379,642,368 バイトの空き領域
C:\tmp>