23種類のデザインモード(17)javaコマンドモード


23種類の設計モードの第17編:java命令モード
定義:一つの要求を一つのオブジェクトにカプセル化し、異なる要求を使用してクライアントをパラメータ化し、要求のキューに入れたり、要求ログを記録したりすることで、コマンドのキャンセルと回復機能を提供することができます。
タイプ:行動パターン
クラス図:

コマンドモードの構造
        名前の通り、コマンドモードはコマンドのパッケージです。まずコマンドパターンの基本構成を見てみます。
Commandクラス:抽象的なクラスです。クラスで実行する命令を声明します。一般的にはexecuteメソッドを公開して命令を実行します。
Concrete Command類:Command類の実現類は、抽象類の中で声明する方法を実現します。
Clientクラス:最終的なクライアントコールクラス。
        以上の三つのタイプの役割は理解しやすいはずです。ここではInvoker類とRecevier類について重点的に説明します。
Invokerクラス:调节者、コマンドの呼び出しを担当します。
Receiver類:受信者は、コマンドを受信し、コマンドを実行します。
        命令のパッケージというのは、一連の操作を一つの方法に書いて、クライアントに呼び出してもいいです。類図に反映して、Concrete Command類とCient類だけでコマンドのパッケージを完成できます。さらにフレキシブルを増やすために、もう一つのCommand類を追加して適切な抽象化ができます。この調合者と受取人は一体どんな役割をしますか?
        実際には、単にいくつかの操作をパッケージ化するだけでコマンドとして他の人に呼び出すことができますが、どのようにモデルと呼ばれることができますか?コマンドモードは行动系のモードとして、まず低いカップリングが必要で、結合度が低いとフレキシブルになります。コマンドモードの共通コードは以下の通りです。

class Invoker { 
    private Command command; 
    public void setCommand(Command command) { 
      this.command = command; 
    } 
    public void action(){ 
      this.command.execute(); 
    } 
  } 
   
  abstract class Command { 
    public abstract void execute(); 
  } 
   
  class ConcreteCommand extends Command { 
    private Receiver receiver; 
    public ConcreteCommand(Receiver receiver){ 
      this.receiver = receiver; 
    } 
    public void execute() { 
      this.receiver.doSomething(); 
    } 
  } 
   
  class Receiver { 
    public void doSomething(){ 
      System.out.println("   -      "); 
    } 
  } 
   
  public class Client { 
    public static void main(String[] args){ 
      Receiver receiver = new Receiver(); 
      Command command = new ConcreteCommand(receiver); 
      //             (        ) 
      command.execute(); 
   
      //              
      Invoker invoker = new Invoker(); 
      invoker.setCommand(command); 
      invoker.action(); 
    } 
  }
コードを通して、私達が呼び出した時、実行のタイミングはまず調整者クラス、そして命令類、最後は受信者クラスです。つまり、一つの命令の実行は三つのステップに分けられています。その結合度はすべての操作を一つのクラスにカプセル化するよりもずっと低いです。これはコマンドモードの本質です。
コマンドモードのメリットとデメリット
        まず、コマンドモードのパッケージ性はとても良いです。各コマンドはすべてカプセル化されています。クライアントにとっては、コマンドが具体的にどのように実行されるかを知ることなく、どのような機能が必要なのかに応じてコマンドを呼び出します。たとえば、ファイル操作のコマンドのセットがあります。ファイルの新規作成、ファイルのコピー、ファイルの削除などです。この三つの操作を一つのコマンドクラスにパッケージすると、クライアントはこの三つのコマンドクラスがあることを知っているだけでいいです。コマンドクラスにパッケージされているロジックについては、クライアントは知る必要がありません。
        第二に、コマンドモードの拡張性が非常に良いです。コマンドモードでは、受信者クラスでは、動作を最も基本的にパッケージ化します。コマンドクラスでは、これらの基本的な操作を二回パッケージ化します。新しいコマンドを追加すると、コマンドクラスの作成は一般的にゼロからではなく、大量の受信者クラスが呼び出し可能です。コマンドクラスの呼び出しも多くあります。コードの多重性がいいです。例えば、ファイルの操作では、ファイルを切り出すコマンドを追加する必要があります。コピーとファイルの削除という二つのコマンドを組み合わせればいいです。とても便利です。
        最後にコマンドモードの欠点を言います。コマンドがたくさんあると開発に頭が痛くなります。特に簡単な命令が多く、実現すれば数行のコードが必要ですが、コマンドモードを使うと命令の種類が簡単ではなく、命令の種類を書いてパッケージ化する必要があります。
コマンドモードの適用シーン
       大多数の要求−応答モードの機能については、コマンドモードの定義で説明したように、コマンドモードはログ記録、キャンセル操作などの機能を実現するのに便利である。
 締め括りをつける
       一つの場合にモードを使うかどうかは、すべての開発者にとって葛藤の問題です。時には、需要を予測する上で発生するいくつかの変化により、システムの柔軟性と拡張性のためにある種類の設計パターンを使用しましたが、この予見の需要はどうしてもなく、逆に、予想していなかった需要は多く来ました。このような例は、どのプログラム設計者にも会ったことがあると信じています。だから、敏捷な開発の原則に基づいて、私達はプログラムを設計する時、もし現在の需要によって、ある種類のモードを使わないでもよく解決できるならば、それを導入しないでください。設計モードを導入するのは難しくないです。本当に必要な時にシステムに対して行って、この設計モードを導入してもいいです。
       コマンドモードで言えば、要求応答モードの機能は非常に一般的です。一般的に、要求に対する応答動作を一つの方法にパッケージ化します。このパッケージの方法はコマンドと言ってもいいですが、コマンドモードではありません。このようなデザインをモードの高さに上げるかどうかは別に考えなければなりません。コマンドモードを使うなら、調整者と受信者の二つのキャラクターを導入します。元々は一つのところに置いていたロジックが三つの種類に分散しています。設計する時、このような価格が価値があるかどうかを考慮しなければなりません。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。