Javascript実践におけるコマンドモードの詳しい説明

Javascript実践におけるコマンドモードの詳しい説明

意味

リクエストをオブジェクトとしてカプセル化することで、異なるリクエストを持つ他のオブジェクトをパラメーター化したり、リクエストをキューに登録したりログに記録したり、元に戻せる操作をサポートしたりできるようになります。

「コマンド パターン」は「リクエスト」をオブジェクトにカプセル化することで、元に戻す操作をサポートしながら、他のオブジェクトを異なるリクエスト、キュー、またはログを使用してパラメータ化できるようにします。

ここでの「リクエスト」の定義は、フロントエンドでよく言われる「Ajax リクエスト」ではなく、アクションを開始することを意味する「アクション リクエスト」です。たとえば、リモコンを使ってテレビの電源を切るときは、「電源を切って」がリクエストになります。コマンド パターンでは、リクエストをコマンドに抽象化します。このコマンドは再利用可能で、受信者 (テレビ) のみを考慮します。アクションの開始側 (リモコン) は、サポートするコマンドのみを考慮しますが、これらのコマンドが具体的に何を行うかは考慮しません。

構造

コマンド パターンのクラス図は次のとおりです。

このクラス図には、5 つの役割があります。

  • クライアント - 具体的なコマンドとレシーバー (アプリケーション層) を作成します。
  • 呼び出し側 - コマンドの発行者。通常はコマンド オブジェクトを保持し、複数のコマンド オブジェクトを保持できます。
  • レシーバー - コマンド レシーバー。実際にコマンドを実行するオブジェクト。コマンドに必要な対応する機能を実装できる限り、どのクラスでもレシーバーになることができます。
  • コマンド - コマンド インターフェース。
  • ConcreteCommand - コマンド インターフェイスの実装。

レシーバーとインボーカーは結合されておらず、機能拡張が必要な​​場合は新しいコマンドが追加されます。そのため、コマンドモードはオープンクローズ原則に準拠しています。

カスタムショートカットキー

ショートカット キーのカスタマイズは、エディターの最も基本的な機能です。コマンド パターンを使用すると、キーの位置とキー ロジックを切り離す構造を記述できます。

インターフェースコマンド{
    実行():void
}

タイプ Keymap = { [キー:文字列]: コマンド }
クラスホットキー{
    キーマップ: キーマップ = {}

    コンストラクタ(キーマップ: キーマップ) {
        this.keymap = キーマップ
    }

    呼び出し(e: キーボードイベント) {
        定数プレフィックス = e.ctrlKey ? 'ctrl+' : ''
        定数キー = プレフィックス + e.key
        this.dispatch(キー)
    }

    ディスパッチ(キー: 文字列) {
        this.keymap[キー].exec()
    }
}

クラスCopyCommandはCommandを実装します{
    コンストラクタ(クリップボード: 任意) {}
    実行() {}
}

CutCommandクラスはCommandを実装します{
    コンストラクタ(クリップボード: 任意) {}
    実行() {}
}

PasteCommandクラスはCommandを実装します{
    コンストラクタ(クリップボード: 任意) {}
    実行() {}
}

const クリップボード = { データ: '' }
定数キーマップ = {
    'ctrl+x': 新しいCutCommand(クリップボード)、
    'ctrl+c': 新しいCopyCommand(クリップボード)、
    'ctrl+v': 新しい PasteCommand(クリップボード)
}
const hotkey = 新しい Hotkey(キーマップ)

document.onkeydown = (e) => {
    ホットキー.call(e)
}

この場合、ホットキーが呼び出し側で、クリップボードが受信者になります。既存のキーマップを変更する必要がある場合は、既存のキーまたはコマンドを追加または置き換えるだけです。

この書き方はお馴染みだと思いますか?はい、Redux もコマンド モードを適用します。Store は Receiver に相当し、Action は Command に相当し、Dispatch は Invoker に相当します。

元に戻すとやり直し

コマンド パターンに基づいて、元に戻すとやり直しをサポートするように簡単に拡張できます。

インターフェース IPerson {
    moveTo(x: 数値, y: 数値): void
}

クラスPersonはPersonを実装します{
    x = 0
    y = 0

    移動先(x: 数値, y: 数値) {
        this.x = x
        this.y = y
    }
}

インターフェースコマンド{
    実行(): 無効
    元に戻す(): 無効
}

MoveCommandクラスはCommandを実装します{
    前X = 0
    前 = 0

    人: 人

    コンストラクタ(人: Person) {
        this.person = 人
    }

    実行() {
        this.prevX = this.person.x
        this.prevY = this.person.y
        this.person.moveTo(this.prevX++、this.prevY++) は、
    }

    元に戻す(){
        this.person.moveTo(this.prevX, this.prevY)
    }
}


const ezio = 新しい Person()
const moveCommand = 新しい MoveCommand(ezio)
移動コマンド.exec()
コンソールログ(ezio.x、ezio.y)
移動コマンド.undo()
コンソールログ(ezio.x、ezio.y)

録音と再生

ゲーム内の録画と再生機能について考えてみましょう。キャラクターの各アクションをコマンドと見なすと、録画中に一連のコマンド キューを取得できます。

クラスコントロール{
    コマンド: コマンド[] = []
    
    exec(コマンド) {
        this.commands.push(コマンド)
        コマンド.exec(this.person)
    }
}

const ezio = 新しい Person()
const コントロール = 新しいコントロール()
control.exec(新しいMoveCommand(ezio))
control.exec(新しいMoveCommand(ezio))

console.log(コントロールコマンド)

コマンド キューがあれば、複数の元に戻す操作とやり直し操作を簡単に実行し、コマンド履歴を実現できます。現在のコマンド キューのポインターを移動するだけです。

クラスコマンド履歴 {
    コマンド: コマンド[] = []
    
    インデックス = 0
    
    現在のコマンドを取得します(){
        this.commands[index]を返す
    }
    
    コンストラクター(コマンド: Command[]) {
        this.commands = コマンド
    }
    
    やり直し(){
        this.index++
        this.currentCommand.exec()
    }
    
    元に戻す() {
        this.currentCommand.undo()
        this.index--
    }
}

同時に、コマンドをオブジェクトにシリアル化すると、保存や送信に使用できるようになります。このようにして、リモート コンピューターに送信し、ezio の動きをリモート制御する機能を実現できます。

[{
    タイプ: '移動'、
    x: 1,
    y: 1,
}, {
    タイプ: '移動'、
    x: 2,
    y: 2,
}]

マクロ

コマンドに対して簡単な処理を行うことで、既存のコマンドを組み合わせて実行し、マクロコマンドとして使用することができます。

クラスBatchedCommandはCommandを実装します{
    コマンド = []
    
    コンストラクタ(コマンド) {
        this.commands = コマンド
    }
    
    実行() {
        this.commands.forEach(コマンド => command.exec())
    }
}

const batchedMoveCommand = 新しいBatchedCommand([
    新しいMoveCommand(ezio)、
    新しいSitCommand(ezio)、
])

バッチ化されたMoveCommand.exec()

要約する

上記の例から、コマンド モードには次の特性があることがわかります。

  • 低結合により、受信者と発信者間の結合が完全に排除されます。
  • 拡張が容易で、新しいコマンドを追加するだけで新しい機能を拡張できます。
  • シリアル化をサポートし、保存と転送が容易になります。
  • これにより、コマンド クラスが簡単に大きくなる可能性があります。

以上がJavascript実践におけるコマンドモードの詳細な説明です。Javascriptコマンドモードの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • メンテナンス可能なオブジェクト指向 JavaScript コードの作成
  • JavaScript を使用してメンテナンス可能なスライドショー コードを作成する
  • JavaScriptのURLオブジェクトとは何かについて話しましょう
  • JavaScript における正規表現の実際的な応用の詳細な説明
  • JavaScript で配列遅延評価ライブラリを実装する方法
  • 独自のネイティブ JavaScript ルーターを作成する方法
  • JavaScript でアルゴリズムの複雑さを学ぶ方法
  • いくつかの面接の質問を使ってJavaScriptの実行メカニズムを調べる
  • メンテナンス可能なJSコードの書き方を教えます

<<:  一般的な MySQL ストレージ エンジンとパラメータ設定およびチューニングの紹介

>>:  Dockerデータボリューム操作の実装

推薦する

Echart Bar の 2 列チャート スタイルの最も完全な詳細な説明

目次序文インストールと設定1. Echartsをインストールする2. Echartsをグローバルに導...

mysql5.7 のエンコーディングを utf8mb4 に設定する方法

最近、問題に遭遇しました。モバイル端末の絵文字や一部の絵文字は 4 バイトですが、UTF-8 は 3...

TypeScript におけるジェネリックケースの詳細な説明

ジェネリックの定義 // 要件 1: ジェネリックは指定されていないデータ型をサポートできるため、渡...

HTMLはシンプルで美しいログインページを作成します

まずは見てみましょう。 HTML ソースコード: XML/HTML コードコンテンツをクリップボード...

HTML フローティング フレーム (iframe 読み込み HTML) の設定と使用の例

コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBLIC "...

Vue 3.0 カスタムディレクティブの使い方

目次1. カスタム指示1. グローバルカスタム指示を登録する2. グローバルカスタム指示を使用する3...

HTML の doctype とエンコーディングに関する簡単な説明

文書タイプDoctype は、指示を解析するためにどのバージョンの HTML を使用するかをブラウザ...

Reactのコンテキストとプロパティの説明

目次1. 文脈1. 使用シナリオ2. 使用手順3. 結論2. 小道具の詳細1. 子供の財産2. 小道...

display:olck/none を使用してメニューバーを作成する方法

display:bolck/none によるメニューバーの完成の効果 図 1:まず、完成したエフェク...

ソースコードから、Vue2がデータとメソッドを直接取得できる理由がわかる

目次1. 例: これはデータとメソッドを直接取得できます2. 環境を準備し、ソースコードをデバッグし...

HTMLタグの書き方でよくある間違い

注意を払う必要があります。HTML Police がコードを調べて、意味のないタグをすべて見つけ出す...

Linux zabbix エージェントの展開と設定方法の詳細な説明

1. web01にzabbix-agentをインストールするZabbix ウェアハウスをデプロイする...

Dockerコンテナのネットワーク管理とネットワーク分離の実装

1. Dockerネットワーク管理1. Dockerコンテナ方式1) Dockerが外部ネットワーク...

Ubuntu システムにおけるネットワーク構成ファイルの分析と説明

今日は奇妙なネットワーク問題に遭遇しました。調査プロセスといくつかの構成状況を記録し、Linux で...

JavaScriptはクリックするとランダムなグラフィックを生成します

この記事では、クリックするとランダムグラフィックの生成を実現するJavaScriptの具体的なコード...