人生は道にのみあり、夢は正面にのみあり、心に問題はなく、道は正直であり、正しい態度はあなたの人生をより穏やかで快適にすることができます。もちろん、メンタリティは自分で調整します。あなたが進んでいる限り、あなたは自分自身に正しいメンタリティを与えることができます。あなたが進んでいる限り、あなたはそれに固執することができます。
デザインパターンの学習、近い将来23のデザインパターンについてブログを書きますので、お
楽しみに〜— 2021/1/16
定義
ソフトウェアシステムでは、「動作要求者」と「動作実装者」は通常、一種の「密結合」を示します。ただし、「記録、元に戻す/やり直し、トランザクション」などの動作の処理など、状況によっては、変更に抵抗できないこの種の緊密な結合は不適切です。この場合、「ビヘイビアリクエスター」を「ビヘイビア実装者」から切り離す方法は?2つの間の疎結合を実現するために、一連の動作をオブジェクトとして抽象化します。これはコマンドパターンです
コマンドモード分析
- コマンドモードの本質は、コマンドをカプセル化し、コマンドを発行する責任とコマンドを実行する責任を分離することです。
- 各コマンドは操作です。要求側は操作を実行するための要求を送信し、受信側は要求を受信して操作を実行します。
- コマンドモードでは、要求側と受信側を独立させることができるため、要求側は、要求の受信方法や、操作が実行されたかどうか、いつ、どのように実行されたかはもちろん、受信側のインターフェイスを知る必要がありません。どのように実行されたか。
- コマンドモードでは、リクエスト自体がオブジェクトになり、他のオブジェクトと同じように保存および送信できます。
- コマンドモードの鍵は、抽象コマンドインターフェイスの導入であり、送信者は抽象コマンドインターフェイス用にプログラムされています。受信者に関連付けることができるのは、抽象コマンドインターフェイスを実装する特定のコマンドのみです。
簡単な理解:
戦争に行きたい場合、将軍は兵士に命令を実行するように命令を出します。将軍は兵士に直接対処することはなく、命令を通じて将軍と兵士を「接続」します。
役割分析
- ICommandは、コマンドインターフェイスを定義するために使用されます
- 兵士は、ICommandコマンドインターフェイスを実装するために兵士を指します
- Admiralは、コマンドを送信するためのICommandコマンドインターフェイスの一般的な統合を指します
- CommandContentは、コマンドの特定のコンテンツを参照します
UML类图(1.1)
:
プロジェクトの要件
たとえば、次のようになります。
- コンピューター
- テレビ
- 携帯電話
- 空調
家電を待つと、それぞれの家電がリモコンに対応します。たとえば、4種類の家電と4種類のリモコンがあり、とても面倒で、コマンドモードではこの4種類の家庭を組み合わせることができます。アプライアンスをリモコンに入れます。リモコンを使用して、これら4つの家電製品を制御します。このように
效果图(2.1)
:
リモコンからコマンドを送信すると、対応する製品がテレビのオンボタンをクリックしてテレビの電源を入れるなどの対応する機能を実現します。
コード
ICommand(コマンドインターフェイス):
public interface ICommand {
//开始
public void start();
//撤回
public void withdraw();
}
CommandContent(コマンド固有のコンテンツ):
public class CommandContent {
String type;
//传递的是家电 比如说电视
public CommandContent(String type) {
this.type = type;
}
public void on(){
Log.i("命令模式",type+" 打开了~ ");
}
public void off(){
Log.i("命令模式",type+" 关闭了~ ");
}
}
TvOffCommand、特定の実装インターフェイス(TVオフ):
public class TvOffCommand implements ICommand{
CommandContent dispatchOrders;
public TvOffCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
//如果点击关闭,执行关闭命令
dispatchOrders.off();
}
@Override
public void withdraw() {
//点击撤销,执行打开命令
dispatchOrders.on();
}
}
TvOnCommand、特定の実装インターフェイス(TVオン):
public class TvOnCommand implements ICommand{
CommandContent dispatchOrders;
public TvOnCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
//如果点击打开,执行打开命令
dispatchOrders.on();
}
@Override
public void withdraw() {
//点击撤销,执行关闭命令
dispatchOrders.off();
}
}
NoCommand(空のコマンド。最初は開いておらず、閉じていないため、最初の初期化に使用されます):
public class NoCommand implements ICommand{
@Override
public void start() {
}
@Override
public void withdraw() {
}
}
CallCommand(コマンド呼び出し元):
public class CallCommand {
//开命令
ICommand[] tvOnCommand;
//关命令
ICommand[] tvOffCommand;
//记录当前存放的命令 用来撤回
ICommand currentCommand;
//默认可存放5条命令
int number = 5;
//初始化命令
public CallCommand() {
tvOnCommand = new ICommand[number];
tvOffCommand = new ICommand[number];
for (int i = 0; i < number; i++) {
//先默认为空的命令
tvOnCommand[i] = new NoCommand();
tvOffCommand[i] = new NoCommand();
}
}
/**
* @param index 当前存放的下标
* @param OnCommand 开始下标
* @param OffCommand 结束下标
*/
public void setTvOnCommand(int index, ICommand OnCommand, ICommand OffCommand) {
this.tvOnCommand[index] = OnCommand;
this.tvOffCommand[index] = OffCommand;
}
/**
* @param index 命令下标
*/
public void getOnCommand(int index) {
this.tvOnCommand[index].start();
//记录当前命令
currentCommand = this.tvOnCommand[index];
}
/**
* @param index 命令下标
*/
public void getOffCommand(int index) {
this.tvOffCommand[index].start();
//记录当前命令
currentCommand = this.tvOffCommand[index];
}
/**
* 撤回
*/
public void getWithdraw() {
currentCommand.withdraw();
}
}
テストコード(クライアント):
//创建打开电视机命令具体内容
CommandContent commandContent1 = new CommandContent("电视机");
//初始化电视机开关命令
TvOnCommand tvOnCommand = new TvOnCommand(commandContent1);
TvOffCommand tvOffCommand = new TvOffCommand(commandContent1);
//创建遥控器
CallCommand callCommand = new CallCommand();
//给遥控器初始化电视机开关命令
callCommand.setTvOnCommand(0,tvOnCommand,tvOffCommand);
//调用遥控器打开命令
callCommand.getOnCommand(0);
//调用遥控器关闭命令
callCommand.getOffCommand(0);
//调用遥控器撤回命令
callCommand.getWithdraw();
Log图(3.1)
:
利点:
- オブジェクト間の結合の程度を減らします。
- 新しいコマンドをシステムに簡単に追加できます。
- 開閉の原則(拡張のために開く、変更のために閉じる)を遵守し、十分に拡張することができます
短所:
- 単純な関数だと、コードやクラスが多くなり、コマンドモードがわからないと読みづらくなります。
- コマンドごとに特定のコマンドクラスを設計する必要があるため、システムによっては、コマンドモードの使用に影響を与える特定のコマンドクラスを多数必要とする場合があります。
拡張する方法
ここで、電話を切り替えるコマンドを追加する必要があるとします。
PhoneOnCommand(電話オープンコマンド):
public class PhoneOnCommand implements ICommand{
CommandContent dispatchOrders;
public PhoneOnCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
dispatchOrders.on();
}
@Override
public void withdraw() {
dispatchOrders.off();
}
}
PhoneOffCommand(電話オフコマンド):
public class PhoneOffCommand implements ICommand{
CommandContent dispatchOrders;
public PhoneOffCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
dispatchOrders.off();
}
@Override
public void withdraw() {
dispatchOrders.on();
}
}
テストコード(クライアント):
//创建命令具体类容
CommandContent commandContent2 = new CommandContent("手机");
//创建手机命令
PhoneOnCommand phoneOnCommand = new PhoneOnCommand(commandContent2);
PhoneOffCommand phoneOffCommand = new PhoneOffCommand(commandContent2);
//设置给遥控器命令
callCommand.setTvOnCommand(1,phoneOnCommand,phoneOffCommand);
//遥控器打开手机
callCommand.getOnCommand(1);
//遥控器关闭手机
callCommand.getOffCommand(1);
//遥控器打开手机
callCommand.getOnCommand(1);
//遥控器撤销
callCommand.getWithdraw();
Log图(3.2)
:
元のコードは変更されていませんが、「コマンド」が少し変更されており、対応するメソッドは引き続き調整できます。
オリジナリティは簡単ではありません、あなたの好きなものは私にとってあなたの最大のサポートです〜