commandとは、命令、指令という意味ですね。
あなたがキーボードで特定の文字列を入力したり、マウスで特定の位置をクリックしたりして、コンピュータを操作する場合、その操作もコマンドと言います。
コンピュータに命令しているわけですから。
ソフトウェアを操作するのは、人間だけではありません。
他のソフトウェアやOSなども、ソフトウェアに対してコマンドを発行します。
コマンドパターンは、命令や操作を扱うパターンです。
コンテンツ
リモコン
あなたのおうちには、リモコンありますよね?テレビ、ハードディスクレコーダー、CDプレイヤー、エアコン、何のものでもいいので、思い浮かべてみてください。
あなたは、リモコンを操作するとき、どういう信号が発信されているのか、気にしますか?
リモコンの先っぽにある赤外線照射器から、どんなタイミングで、どんな強さの光が、どういうリズムで出ているのか。
そんなの知ったことか…ですよね。
リモコンは、そういう面倒くさいことを、全部あなたに秘密にしておいてくれます。
だから、あなたはリモコンのボタンをぽちっと押すだけで、快適な生活を楽しむことができます。
たとえばエアコンのリモコンには、運転開始/停止、温度を上げる、下げる、暖房/冷房切り替え、風量調節、風向き調節など、いろんなボタンがありますね。
エアコンのリモコンは、押されたボタンによって、それぞれ全く違った動作をしているのでしょうか?
運転開始/停止ボタンを押したときと、風量調節ボタンを押したときでは、電圧が違う?電流の向きは?
同じですね。
どのボタンが押されたときでも、リモコンがやることは赤外線を発射することです。
あなたと電化製品の間に
ここで、リモコンを操作するあなたを依頼者―クライアント、操作を受ける機器をレシーバと言い換えてみましょう。- クライアントからは、実際に何が行われているかを隠す
- レシーバからは、操作方法を分離する
コマンドは、クライアントとレシーバの間に存在します。
クライアントとレシーバを分離し、橋渡しをするのです。
このような立場のものや、その集合によって成り立つ概念上の層を、分離レイヤ―アイソレーションレイヤと言います。
リモコンはコマンドパターンの身近な実例です。
リモコンのボタン一つ一つが、それぞれ一つのコマンドを表しています。
どれかのボタンを押すと、そのボタンに割り当てられていたコマンドが実行されるわけです。
リモコンのおかげで、私たちは機器の詳しい構造を知らなくても、簡単に操作することができます。
取り替えやすい
コマンドパターンは、このように操作自体をオブジェクトとしてとらえるものです。そうすることで、操作自体と、操作を受け付けるオブジェクト―レシーバを分離します。
コマンドパターンならではの特徴は、他にもあります。
買い替え用のリモコンがそれです。
便利なのがいろいろありますよね。
テレビ、ビデオ、DVD、ハードディスクレコーダーなどが1台のリモコンで操作できたり、ソーラーパネルで電池いらずだったり。
こんなふうに、自由にリモコンを取り替えることができるのは、リモコンが、あなたが何をしたいかを本体に伝えるためだけのものだからです。
機器本体のこまごまとした構造やなんかと完全に切り離されているおかげなのです。
コマンドは、取り替えや変更が簡単なのです。
マクロ
ところで、便利さも、上には上があるものです。最近のリモコンは、単に操作をそのまま伝えるだけのものでは、なくなってきているようです。
たとえばLogicool Harmony リモートコントローラー HM-882なんて、ボタン1発でテレビ、ハードディスクレコーダー、オーディオ機器など、設定しておいた全ての機器の電源を入れて、入力切り替えもしてくれちゃって、万全の体制を整えてくれます。
この機能をちょっと考えてみましょう。
テレビやハードディスクレコーダーなどいろんな機器は、このリモコンを使って、それぞれ個別に電源を入れたり、入力を切り替えたりもできます。
で、本来一つ一つ人間が押していくはずのボタンの機能が、あるボタンを押した場合には、自動的に次々と実行されるわけですね。
このように、一発でいろいろやってくれちゃうボタンというのは、他のいくつかのボタンの機能をいっぺんに実行するという機能を持っているんですね。
要するに、これはマクロボタンなわけです。
リモコンのボタン一つ一つがコマンドだということを思い出して下さい。
このことは、コマンドがコマンドを包含していると言えますね。
これ、何かに似てませんか?
そう、コンポジットパターンです。
このように、コマンドにコンポジットパターンの構造をもたせることで、マクロを組み上げることもできるようになります。
リモコン以外にも、本体と操作を切り離すことで、とらえやすくなる例はありませんか?
身の回りを、探してみてください。
ソフトウェア開発者の方のための追記
実装では、Command抽象クラスを用意し、そこから派生させてさまざまな具象コマンドを作るのが一般的です。抽象クラスには、例えばexecute()のようなコマンド実行用の抽象メソッドを持たせます。
こうすることで、クライアント側は全てのコマンドを、抽象クラスの型で同じように扱うことができます。
具象クラスは、コンストラクタでレシーバを受け取り、execute()メソッド内で実際の処理を行います。
このとき、レシーバはインターフェイスであるべきです。
でないと、レシーバとコマンドが密結合してしまいます。
GUIアプリケーションでは、コマンドパターンの利用は欠かせません。
たとえば、コマンドパターンによって、アプリケーション本体から操作を切り離し、それぞれをメニューアイテムに関連づけるようにします。
そうすることで、同じコマンドがツールバーでも、状況依存のコンテキストメニューでも使いまわせるようになります。
また、コマンドに、操作を元に戻す機能を持たせることで、アンドゥをサポートすることもできます。
実行されたコマンドを履歴リストに保存しておいて、順に元に戻す機能を実行していくのです。
再度通常の実行を行えば、リドゥもできます。
オススメ
パターンは、決まったフォーマットにのっとって書かれていなければなりません。情報を均質にすることで、パターン同士を比較しやすくするためです。
ソフトウェアを設計する際に、最適なパターンを選択できるようにするためには、このことは非常に重要です。
しかし、このブログは、フォーマットには全くのっとらずに書いています。
そればかりか、本来はお伝えすべき重要なことですら、全てお伝えしているわけではありません。
それぞれのパターンのエッセンスを理解していただくことを目標としているからです。
わかりやすさを優先するため、割愛している情報も多くあります。
この本で、全ての情報を、しっかりと把握されることを、強くオススメします。
このブログは、そうされることを前提として書いています。
他のサイトや本を参考になさるとして、もしそこにこのような注意書きがなかったとしても、やはりこれは必要なことです。
何を参考になさるにしろ、オブジェクト思考における再利用のためのデザインパターンだけは読まれることを、強くオススメします。
【Javaの勉強はじめました】 の管理人のライトニンです。先日はアドバイスありがとうございました。近いうちにオブジェクト指向の勉強をはじめようと思います。
返信削除ところで、craftsmanさんのブログ【オブジェクト思考】をリンク集「プログラマのブログ」に登録させていただきました。
リンクさせていただきましたページは、
http://javajavajava.seesaa.net/article/34739544.html
です。
万一何か不都合がございましたらすぐに削除、修正しますのでご連絡ください。
とんでもございません。
返信削除ありがとうございます。
不都合全然ございません。
オブジェクト指向の勉強は、プログラミングの勉強とは、また違ったおもしろさがあります。
楽しんでください。
私も、まだまだ学ぶべきことがたくさんあります。
お互い、楽しくがんばっていきましょう。