前置き
Commandパターンを実装していて、戻り値を返したくなった。しかし、CommandパターンのExecute()はvoidなので戻り値を返せない。どうすれば?
対処法
stackoverflow によると、Execute()の戻り値をGeneric型にすれば良いらしい。
// 戻り値を返すコマンド
interface Command<T>
{
T Execute();
}
class ConcreteCommandWithResult : Command<int>
{
private Receiver _receiver;
:
public int Execute()
{
return _receiver.GetValue();
}
}
これで確かに戻り値は返せるようになったが、戻り値を返さなくて良いコマンドもある場合、
C# のGeneric型は void を指定できないので、 Command<void>
と Command<T>
で分ける必要がある。
// 戻り値を返すコマンド
interface Command<T>
{
T Execute();
}
class ConcreteCommandWithResult : Command<int>
{
private Receiver _receiver;
:
public int Execute()
{
return _receiver.GetValue();
}
}
// 戻り値を返さないコマンド
interface Command
{
void Execute();
}
class ConcreteCommand : Command
{
private Receiver _receiver;
:
public void Execute()
{
return _receiver.Action();
}
}
これでCommandパターンを満たせる。
おわりに
なんかしっくり来ないんだよねぇ…。
そもそもCommandパターンってCommandを別々に分けていいものなの?的な。
GoFのCommandパターンはCommandインターフェース1つで実現してるのに、上記の解決方法だとCommandインターフェースが2つ必要になってしまう。
そうなると Invoker が Invoker じゃなくて Facade みたいな扱いになるんじゃないかなと。
うーん…わからん。