Ruby設計モードのプログラミングにおける命令モードの関連使用を深く分析する。


コマンドモードは対象行動型の使用率が高いデザインモードで、別名:アクション、Transation(事務)
意図:一つの要求を一つの対象としてカプセル化し、異なる要求をパラメータ化できるようにする。キューの要求や要求ログの記録、キャンセル可能な操作をサポートします。
ここで「異なる要求」とは、要求が起こる可能性のある変化を意味するだけでなく、拡張可能な機能点である。
動機:広がりやすい
構造:
201646111037926.png (396×266)
連携説明:
   参加キャラクター:
    Commandはある操作を実現するためのインターフェースを宣言します。
    Concrete Commundは動作をReciverと外付けし、Reciverオブジェクトの対応する方法を呼び出してCommandを実現する方法です。
    ClientはConcrete Commandオブジェクトを作成し、そのReciverオブジェクトを設定します。
Invokerは、Commandリクエストの実現を要求する。
Reciverは、具体的なお願いをどうやって実現するかを知るクラスです。
クライアントは具体的なCommandオブジェクトを作成し、その受信者を指定しました。
この具体的なCommandオブジェクトは転用者オブジェクトに格納されています。
現在の要求は、CommandオブジェクトのExecute方法を実行することによって実行される。
コマンドがキャンセル可能である場合、具体的なオブジェクトは、実行方法を呼び出す前に、この要求を命令するために対応する状態を格納します。
具体的なCommandオブジェクトは、その受信者の方法を呼び出して、対応する要求を実現する。
適用性:
MenuItemに似ています。実行する動作を抽象化して、あるオブジェクトをパラメータ化します。
異なる時刻に指定、整列、実行要求
元に戻すことをサポートします
変更ログのサポート
原語操作上に構築された高層オペレーティングシステム(つまり、事務)
ダイナミック:rubyのようにblockはコマンドモードです。
効果:
コマンドモードは、使用者オブジェクトを受信対象とデカップリングする(呼び出しとデカップリングを実現する)。使用者が機能を実現する場合は、CommandインターフェースのExecuteメソッドを呼び出すだけです。
具体的なCommundsオブジェクトは第1層のオブジェクトで、他のオブジェクトのように拡張されたり操作されたりすることができます。
複数のCommundsオブジェクトを一つのコンビネーションコマンドにまとめることができます。コンビネーションコマンドは、合成対象モードの一例でもあり、コマンドをキューに入れることも特殊な場合です。
既存のコードを修正する必要がないので、簡単に新しいコマンドを追加できます。これは開閉の原則にも合致しており、開閉の変更に対しては、拡張開放されています。
命令対象がどのような知能プログラムに達するべきかという問題と、元に戻すべきか、やり直すべきかを考えるべきです。
誤用:
どっちが簡単なの?
命令モードは「これをやる」というのではなく、「これを覚えてどうするか」と言って、後でまた言います。先ほど覚えてほしい方法でこれを作ります。
注意して取り消すと、多くの操作が破壊されます。ファイルを削除する操作などです。
クラス図:
201646111142669.jpg (574×253)

class Button
 
 attr_accessor :name, :command
 
 def initialize name, command
  @name = name
  @command = command
 end
 
 def do_something
  @command.execute
 end
 
end

class Command
 
 def execute
  "root execute"
 end
 
end

class PaintCommand < Command
 
 def execute
  "draw something"
 end
 
end

class VocalCommand < Command
 
 def execute
  "talk something"
 end
 
end

paintCommand = PaintCommand.new
vocalCommand = VocalCommand.new
button = Button.new("button", paintCommand)
p button.do_something
button.command = vocalCommand
p button.do_something

 ボディクラスを定義したButtonは、コマンドオブジェクトCommandを統合し、Command、PaintCommand、VocalCommandの3つの継承を持つコマンドクラスがあり、システムの中に複数のButtonが存在する可能性があります。各Buttonが達成することは違っています。つまり、この部分は変化しています。つまり、方法douです。somethingのコードも不確定で、この部分のコードを個別のオブジェクトに分離して管理していますが、このオブジェクトはコマンドオブジェクトと呼ばれ、コマンドオブジェクトは完成すべきタスクやコマンドだけを担当しています。本体オブジェクトは自分の必要に応じていつでも必要なコマンドを呼び出して実行できます。コール先のコードの中でも、現在のButtonを切り替えるコマンドは非常に便利で、非常に柔軟です。簡単なセット方法だけで完成できます。Button継承の関係を採れば、第一主体のオブジェクトはクラス爆発を起こし、第二はスイッチングコマンドが実現された時点でこの方式を比較するのは難しいです。
 
ルビープロを使用してコマンドモードを完了します。 :
 

class Button
 
 attr_accessor :name
 
 def initialize name, &command
  @name = name
 end
 
 def do_something &command
  command.call
 end
 
end

paint_command = lambda do
 p "paint something"
end

vocal_command = lambda do
  p "talk something"
end

button = Button.new ("name")
button.do_something &vocal_command
button.do_something &paint_command

 コマンドクラスの代わりにblockを使うのがもっと簡単で分かりやすいです。実際のプロジェクト環境ではprocとコマンドを使うことができます。コマンドオブジェクトが非常に複雑で、自分の状態と方法が必要であれば、コマンドクラスを使って完成します。簡単な処理だけであれば、procを採用することができます。
 
実行するコマンドが多すぎると、コマンドキューを定義することができます。つまり、一つのコマンドの中で複数のコマンドを管理しています。呼び出し時に、それぞれのコマンドを呼び出して実行します。この点からは、コンビネーションモードとよく似ています。
 
ある意味で観察者モードとコマンドモードは似ていますが、共通の特徴を持ついくつかのオブジェクトを自分のクラスに集めて、状況に応じて呼び出します。しかし、2つのモードは明らかな違いがあります。用途です。観察者モードは、観察者が変化を観察者にそれぞれの観察者に通知するために使用されますが、コマンドモードは他のコマンドに通知されたかどうかに関わらず、命令対象は自分のタスクやコマンドだけを実行し、コマンドモードは前の操作を記憶することができます。