Javascriptで戦略パターンを実装する方法

Javascriptで戦略パターンを実装する方法

概要

戦略パターンは、JavaScript デザイン パターンにおける動作デザイン パターンです。

意味:

一連のアルゴリズムを定義し、これらの各アルゴリズムを戦略クラス(メソッド)にカプセル化し、変更されない部分と可変部分を分離すると、これらのアルゴリズムを互いに置き換えることができます。

俗語による説明:

実際、いわゆる戦略モードは、異なる戦略に従って異なるメソッドを実行することを指し、if-else 分岐判断と非常によく似ていますが、戦略モードは複数の条件判断ステートメントを解決するために使用されます。

コードの実装

必要:

年末が近づいてきたため、ある企業は年末ボーナスを前倒しで支給することを決めました。しかし、年末ボーナスの計算には一定のルールがあり、年末ボーナスの額は業績評価と密接に関係しています。そのため、ある企業の年末ボーナス計画は次のようになります。

業績評価がSの従業員の場合、年末ボーナスは月給の4倍になります。

業績評価がAの従業員の場合、年末ボーナスは月給の3倍になります。

業績評価がBの従業員の場合、年末ボーナスは月給の2倍になります。

これを見て、プログラムを書き始めることができます。一般的に、ほとんどのコードは次のようになります。

関数 calculateBonus(レベル, 給与){
    if(レベル === 'S'){
        給与の返還*4
    }
    
    if(レベル === 'A'){
        給与返還*3
    }

    if(レベル === 'B'){
        給与返還*2
    }
}

console.log(calculateBonus("S",14000)); //56000
console.log(calculateBonus("A",10000)); //30000
console.log(calculateBonus("B",5000)); //10000

上記のコードを使用して現在のニーズを解決することに問題はありませんが、プログラム設計の観点から、上記のコードはまだ最適化できます。この方法は比較的大きく、分岐判断が多く、柔軟性に欠けるため、年末ボーナスプランが変更された場合、Cプランを追加する必要がありますか?メソッドに分岐判断を追加する必要がありますか?これはオープン・クローズ原則に違反します。

最適化:

var 戦略 = {
    "S": 関数(給与){
        給与返還*4
    },
    "A": 関数(給与){
        給与の返還*3
    },
    "B": 関数(給与){
        給与返還*2
    }
}

var calculateBonus =function(level,salary){
    リターン戦略[レベル](給与);
} 
console.log(calculateBonus("S",14000)); //56000
console.log(calculateBonus("A",10000)); //30000
console.log(calculateBonus("B",5000)); //10000

上記のコードを最適化した後、戦略パターンを使用してコードを変換します。戦略オブジェクトを定義し、calculateBonus がユーザーが渡したレベルと給与に応じて年末ボーナスの金額を計算できることがわかります。変換後、コードの構造はより簡潔になります。

Web 開発では、ログイン ページの登録機能とログイン機能はすべてフォームの送信を必要としますが、送信プロセス中に検証とスクリーニングを実行する必要があり、検証ルールを満たさないものは直接送信されません。デザイン パターンを学習する前は、検証も上記と同じで、複数の if ブランチを使用していましたが、現在は戦略パターンを使用してフォーム検証を実装しています。

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <meta http-equiv="X-UA-compatible" content="ie=edge">
    <title>ドキュメント</title>
</head>
<本文>
        <フォームアクション="http://xxx.com/register" id="registerForm" メソッド="post">
            ユーザー名を入力してください: <input type="text" name="userName"/ >
            パスワードを入力してください: <input type="text" name="password"/ >
            電話番号を入力してください: <input type="text" name="phoneNumber"/ >
            <button>送信</button>
        </フォーム>
</本文>
<スクリプト>
        // 戦略クラスのアルゴリズム検証ルールを定義する var strategies = {
        isNonEmpty: 関数(値、エラーメッセージ){
            if ( 値 === '' ) {
                errorMsg を返します。
            }
        },
        minLength: 関数(値、長さ、エラーメッセージ){
            (値の長さ<長さ)の場合{
                errorMsg を返します。
            }
        },
        isMobile: 関数(値、エラーメッセージ){
            if ( !/(^1[3|5|8][0-9]{9}$)/.test( 値 ) ){
                errorMsg を返します。
            }
        }
    };
    //バリデータクラス var Validator = function(){
        // 検証ルールを保存します this.cache = [];
    };
    //検証ルールを追加するメソッド Validator.prototype.add = function( dom, rules ){
        var self = this;
        for ( var i = 0, ルール; ルール = ルール[ i++ ]; ){
            (関数(ルール){
                //検証ルールオブジェクト内の戦略属性の値を分割します。var strategyAry = rule.strategy.split( ':' );
                var errorMsg = ルール.errorMsg;
                self.cache.push(関数(){
                    //検証ルール オブジェクトの strategy 属性の最初の値を返して、それを strategy に格納します。var strategy = strategyAry.shift();
                    // 構成パラメータ strategyAry.unshift( dom.value );
                    //アセンブリパラメータ strategyAry.push( errorMsg );
                    //戦略オブジェクトの実行メソッドを見つけて、それをキャッシュ変数に格納します。 return strategies[ strategy ].apply( dom, strategyAry );
                });
                console.log(戦略Ary);
            })( ルール )
        }
    };
    //検証メソッドを開始する Validator.prototype.start = function(){
        ( var i = 0, validatorFunc; validatorFunc = this.cache[ i++ ]; ){
             //ループキャッシュ実行メソッドの検証 var errorMsg = validatorFunc();
            //実行戦略オブジェクトメソッドで errorMsg が返された場合、メソッドがエラーを報告した (検証ルールに合格できなかった) ことを意味します。
            if (エラーメッセージ){
                errorMsg を返します。
            }
        }
    };

    // 検証を呼び出す var registerForm = document.getElementById( 'registerForm' );
    //検証ルールをカスタマイズするメソッドを定義する var validataFunc = function(){
        //オブジェクトをインスタンス化します var validator = new Validator();
        //検証ルールをカスタマイズvalidator.add(registerForm.userName, [{
            戦略: 'isNonEmpty'、
            errorMsg: 'ユーザー名は空にできません'
        }, {
            戦略: 'minLength:6',
            errorMsg: 'ユーザー名は 10 文字未満にすることはできません'
        }]);
        バリデーター.add( registerForm.password, [{
            戦略: 'minLength:6',
            errorMsg: 'パスワードの長さは 6 文字未満にできません'
        }]);
        //ループ内で検証を実行するメソッドを呼び出します var errorMsg = validator.start();
        errorMsg を返します。
    }
    //送信ボタンをクリックする(送信イベント)
    registerForm.onsubmit = 関数(){
        //上記のカスタム検証メソッドを実行します var errorMsg = validataFunc();
        //errorMsgが存在する場合、検証が失敗したことを意味します if (errorMsg){
            アラート ( errorMsg );
            false を返します。
        }

    };
</スクリプト>
</html>

戦略パターンを使用すると、フォーム検証における大規模な繰り返し if-else 判断などの問題を解決できます。上記のコードには詳細なコメントを付けました。デザイン パターンを学ぶには、コードを注意深く味わい、アイデアを学ぶ必要があります。とにかく、戦略パターンの主なアイデアの 1 つは、一連のアルゴリズムを定義し、パラメーターを渡し、異なるパラメーターに応じて異なるアルゴリズム ルールを実行することです。

要約する

アドバンテージ:

1. 複数の条件選択ステートメントを回避するために、組み合わせ、委任、およびポリモーフィズムのテクノロジとアイデアを使用します。

2. アルゴリズムを独立した戦略クラスにカプセル化し、切り替え、理解、拡張を容易にします。

3. 戦略パターンはシステムの他の部分で再利用できるため、コピーと貼り付けの作業を繰り返す必要がなくなります。

欠点:

1. 多くの戦略クラスまたは戦略オブジェクトがプログラムに追加されます。

2. 戦略クラスを使用する場合は、すべての戦略アルゴリズムを明確に理解している必要があります。そうでないと、選択方法がわかりません。

上記はJavaScript戦略パターンの詳細です。JavaScript戦略パターンの詳細については、123WORDPRESS.COMの他の関連記事をご覧ください。

以下もご興味があるかもしれません:
  • フォーム検証からのJavaScript戦略モードの使用の詳細な説明
  • JavaScript デザインパターン戦略パターン実装原則詳細説明
  • JSフォーム検証プラグインデータとロジック分離操作例分析[戦略モード]
  • JavaScript デザインパターン - 戦略パターンの原則と使用例
  • JS デザインパターンにおける戦略パターンの概念と使用法の分析
  • JavaScriptは非同期検証フォームを同期フォームに書き換えます
  • js がフォームを検証した後にフォームを送信する 3 つの方法の概要
  • JavaScript戦略モードを簡単にマスター
  • JavaScript 戦略パターンを使用してフォームを検証する方法

<<:  LinuxにDockerをインストールする(非常に簡単なインストール方法)

>>:  本番環境でのMySQLパラメータsql_safe_updatesの使用に関する詳細な説明

推薦する

Tomcat を使用して Centos 環境に SpringBoot WAR パッケージをデプロイする

戦争パッケージを準備する1. 既存のSpringBootプロジェクトを準備し、pomに依存関係を追加...

TypeScriptの列挙型を詳しく説明する

目次1. デジタル列挙2. 文字列の列挙3. 逆マッピング4. 異種列挙5. 定数列挙6. 列挙メン...

div を下から上にスライドさせる CSS3 の例

1. まず、CSS3 のターゲット セレクターを使用し、a タグを使用して id セレクターを指定し...

MySQL準備原理の詳細な説明

準備のメリットPrepare SQL が生成される理由。まず、MySQL サーバー上で SQL を実...

Angular のパフォーマンス最適化: サードパーティ コンポーネントと遅延読み込みテクノロジー

目次概要環境の準備プロジェクトのパフォーマンスに影響を与える要因遅延読み込みとは何ですか?プロジェク...

入力タイプ=テキスト値=str を使用するための不完全なソリューション

今日、非常に奇妙な問題に遭遇しました。次のコードを見てください。 SimpleDateFormat ...

TypeScriptにおけるunknownとanyの違いについて詳しく説明します

目次序文1. 不明 vs 任意2. 未知とあらゆるもののメンタルモデル3. まとめ要約する序文any...

VMware vCenter 6.7 のインストール プロセス (グラフィック チュートリアル)

背景当初は VMware の公式 Web サイトから 6.7 Vcenter をダウンロードしたかっ...

Linux で rpm パッケージを見つけるために CD をマウントする方法

前面に書かれたLinux を使用する際にソフトウェアをインストールする必要がある場合があります。もち...

Vue3 を使用して虫眼鏡効果を実現する方法の例

目次序文1. カプセル化の重要性2. どのようにカプセル化しますか? 1. 準備2. 梱包を開始する...

Linux サービスでファイアウォールを有効にする 2 つの方法

方法は2つあります: 1. サービス方法ファイアウォールのステータスを確認します。 [root@ce...

MySQL クエリ ステートメントのプロセスと EXPLAIN ステートメントの基本概念とその最適化

ウェブサイトやサービスのパフォーマンスは、データベースの設計(適切な言語開発フレームワークを選択した...

Vue ページレンダリングにおけるキーの適用例チュートリアル

導入フロントエンドプロジェクトの開発プロセスでは、el-table によって表示される結果列がコンポ...

MySQLが正常にインストールされたかどうかを確認する方法

MySQL をインストールした後、DOS ウィンドウまたは MySQL 5.7 コマンドライン クラ...

JS 1次元配列を3次元配列に変換する例

今日、CSDN の Q&A セクションで友人が質問をしているのを見ました。彼は 1 次元配列...