パターンの設計を続けます。今日は、定義は言うまでもなく、コマンドパターンを導入します。
定義:「リクエスト」をオブジェクトにカプセル化して、さまざまなリクエスト、キュー、またはログを使用して他のオブジェクトをパラメータ化できるようにします。コマンドモードは、取り消し可能な操作もサポートしています。
このNimaの定義は見るのが面倒ですが、理解できない場合は落ち着いてください。少し単純化します。リクエストをオブジェクトにカプセル化し、アクションリクエスタとアクションエグゼキュータを分離します。わかりました、例を使用して説明します。
需要:最近、スマート家電は非常に熱くなっています。将来、ニマは冷蔵庫がAlipayを使用して自動的に物を買うと予測しています。テレビ、コンピューター、照明、その他の家電があるとすると、すべての家電のスイッチを制御するためにリモコンを作る必要があります。各ボタンに対応する機能はユーザー向けにパーソナライズでき、新しく購入した家電製品に対して非常に強力なスケーラビリティを備えている必要があります。
この要件を見て、Nyimaにパーソナライゼーションと拡張性がない場合は、それについて話しても大丈夫です。各リモートコントロールボタンのonClickを直接ターゲットにし、コードを記述してそれを実行しますが、どのようにパーソナライズされているかには、拡張機能が必要ですセックス。。。
さて、次のコマンドモードが出てきます。コマンドモードのコアは、コマンドをクラスにカプセル化することです。コマンドエグゼキュータは、実行されている特定のコマンドを知る必要はありません。
1.まず、私たちが持っている家電のAPIを見てみましょう。
package com.zhy.pattern.command;
/**
* 门
* @author zhy
*
*/
public class Door
{
public void open()
{
System.out.println("打开门");
}
public void close()
{
System.out.println("关闭门");
}
}
package com.zhy.pattern.command;
/**
* 电灯
* @author zhy
*
*/
public class Light
{
public void on()
{
System.out.println("打开电灯");
}
public void off()
{
System.out.println("关闭电灯");
}
}
package com.zhy.pattern.command;
/**
* 电脑
* @author zhy
*
*/
public class Computer
{
public void on()
{
System.out.println("打开电脑");
}
public void off()
{
System.out.println("关闭电脑");
}
}
ライト、コンピューター、ドアがあり、スイッチのインターフェースは設計されているようです。次に、コマンドをクラスにカプセル化する方法を見てみましょう。
package com.zhy.pattern.command;
public interface Command
{
public void execute();
}
package com.zhy.pattern.command;
/**
* 关闭电灯的命令
* @author zhy
*
*/
public class LightOffCommond implements Command
{
private Light light ;
public LightOffCommond(Light light)
{
this.light = light;
}
@Override
public void execute()
{
light.off();
}
}
package com.zhy.pattern.command;
/**
* 打开电灯的命令
* @author zhy
*
*/
public class LightOnCommond implements Command
{
private Light light ;
public LightOnCommond(Light light)
{
this.light = light;
}
@Override
public void execute()
{
light.on();
}
}
package com.zhy.pattern.command;
/**
* 开电脑的命令
* @author zhy
*
*/
public class ComputerOnCommond implements Command
{
private Computer computer ;
public ComputerOnCommond( Computer computer)
{
this.computer = computer;
}
@Override
public void execute()
{
computer.on();
}
}
package com.zhy.pattern.command;
/**
* 关电脑的命令
* @author zhy
*
*/
public class ComputerOffCommond implements Command
{
private Computer computer ;
public ComputerOffCommond( Computer computer)
{
this.computer = computer;
}
@Override
public void execute()
{
computer.off();
}
}
コマンドはたくさんあるので、デザインの原則によると、スーパータイプのコマンド、そして各サブカテゴリが必要です。各コマンド(リクエスト)をカテゴリにカプセル化していることを確認してください。次に、リモコンを見てください。
package com.zhy.pattern.command;
/**
* 控制器面板,一共有9个按钮
*
* @author zhy
*
*/
public class ControlPanel
{
private static final int CONTROL_SIZE = 9;
private Command[] commands;
public ControlPanel()
{
commands = new Command[CONTROL_SIZE];
/**
* 初始化所有按钮指向空对象
*/
for (int i = 0; i < CONTROL_SIZE; i++)
{
commands[i] = new NoCommand();
}
}
/**
* 设置每个按钮对应的命令
* @param index
* @param command
*/
public void setCommand(int index, Command command)
{
commands[index] = command;
}
/**
* 模拟点击按钮
* @param index
*/
public void keyPressed(int index)
{
commands[index].execute();
}
}
package com.zhy.pattern.command;
/**
* @author zhy
*
*/
public class NoCommand implements Command
{
@Override
public void execute()
{
}
}
リモートコントロールには9つのボタンがあり、各ボタンの機能とクリックを設定する方法があることに注意してください。また、空のオブジェクトと呼ばれるNoCommandオブジェクトを使用していることにも注意してください。このオブジェクトの利点は、事前に実行する必要がないことです。どちらもif(!= null)を判断し、一貫した操作を提供します。
最後に、コードをテストします。
package com.zhy.pattern.command;
public class Test
{
public static void main(String[] args)
{
/**
* 三个家电
*/
Light light = new Light();
Door door = new Door();
Computer computer = new Computer();
/**
* 一个控制器,假设是我们的app主界面
*/
ControlPanel controlPanel = new ControlPanel();
// 为每个按钮设置功能
controlPanel.setCommand(0, new LightOnCommond(light));
controlPanel.setCommand(1, new LightOffCommond(light));
controlPanel.setCommand(2, new ComputerOnCommond(computer));
controlPanel.setCommand(3, new ComputerOffCommond(computer));
controlPanel.setCommand(4, new DoorOnCommond(door));
controlPanel.setCommand(5, new DoorOffCommond(door));
// 模拟点击
controlPanel.keyPressed(0);
controlPanel.keyPressed(2);
controlPanel.keyPressed(3);
controlPanel.keyPressed(4);
controlPanel.keyPressed(5);
controlPanel.keyPressed(8);// 这个没有指定,但是不会出任何问题,我们的NoCommand的功劳
}
}
出力結果:
どのボタンも任意のコマンドで自由に構成でき、Nimaがコードを変更する必要はなく、ユーザーはとにかくそれをパーソナライズできます。実際、それは白であり、完全に分離された構成ファイルでここで設定を構成することもできます。
まあ、ユーザーはこのボタンに満足しすぎないかもしれません。ユーザーは真夜中に直接ドアを閉め、ライトをオフにし、コンピューターをオンにするボタンを提供できることを望んでいます。みんなが理解しているように、コードを少し変更して彼を満たす
コマンドを定義すると、ユーザーは一連のことを実行でき、構成可能であり、インターフェースを元のコマンドと一致させます。
package com.zhy.pattern.command;
/**
* 定义一个命令,可以干一系列的事情
*
* @author zhy
*
*/
public class QuickCommand implements Command
{
private Command[] commands;
public QuickCommand(Command[] commands)
{
this.commands = commands;
}
@Override
public void execute()
{
for (int i = 0; i < commands.length; i++)
{
commands[i].execute();
}
}
}
さて、Diaosiのニーズは満たされました。テストして見てみましょう。
// 定义一键搞定模式
QuickCommand quickCommand = new QuickCommand(new Command[] { new DoorOffCommond(door),
new LightOffCommond(light), new ComputerOnCommond(computer) });
System.out.println("****点击一键搞定按钮****");
controlPanel.setCommand(8, quickCommand);
controlPanel.keyPressed(8);
完璧ですか?
最後に、コマンドモードについて説明します。コマンドモードでは、コマンドをオブジェクトにカプセル化し、アクションリクエスタをアクションエグゼキュータから完全に切り離します。上記の例では、リモコンのボタンは電化製品とは関係ありません。
キューは定義で言及されていることに注意してください。コマンドモードがキューでどのように使用されるかを示します。たとえば、レストランには料理を注文する場所が多く、調理する場所があります。注文は注文と見なされ、調理は注文の実行者と見なされ、常に人々がいます注文は料理をキューに追加することと同じです。料理をする人は、キューから料理を取り出して1つ作るだけです。
ログは定義にも記載されています。ログは通常、ユーザーの動作を記録したり、例外から回復したりするために使用されます。たとえば、各コマンドには2つのメソッドが含まれています。1つは実行、もう1つは元に戻します(上の例では、便宜上、取り消しを書き込みます)、ユーザーの不適切な操作、異常な電化製品など、ユーザーのすべてのコマンド呼び出しをログに保存し、ログ内のすべてのコマンドを取り出して、取り消しを実行するだけで、完全に復元されます。意味。
さて、みんなの応援はコメントといいね、ありがとうございます〜