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の使用に関する詳細な説明

推薦する

VueはEChartsを使用して折れ線グラフと円グラフを実装します

バックエンド管理プロジェクトを開発する場合、バックエンドのユーザーデータをカウントし、折れ線グラフや...

MySQL 外部キー制約の詳細な説明

公式ドキュメント: https://dev.mysql.com/doc/refman/5.7/en/...

Vueは遅延読み込みによりページの応答速度を向上

目次概要遅延読み込みとは何ですか?最適化を開始するビジネスモジュールを分割する遅延読み込みルート構成...

Dockerコンテナでアプリケーションサービスを自動的に起動する方法の例

コンテナの起動時に Docker コンテナ内のアプリケーション サービスを自動的に起動する場合。 D...

mysqldumpデータエクスポートの問題に関する詳細な議論

1. mysqldump の使用時にエラー (1064) が報告されます。これは、mysqldump...

MySQL イベント スケジューラに関するよくある話 (必読)

概要MySQL には独自のイベント スケジューラもあり、これは Linux の crontab ジョ...

Keepalived は Nginx の負荷分散と高可用性のサンプル コードを実装します

第1章: keepalivedの紹介VRRP プロトコルの目的は、静的ルーティングの単一点障害問題を...

dockerでビルドしたnacos1.3.0の実装

1. nacosデータベースを再開します。データベース名nacos_configユーザー名とパスワー...

IE6/IE7/IE8/IE9/FF 向け CSS ハック (概要)

IE8.0の正式版をインストールしたので、基本的なCSS HACKをいくつかまとめてみました。We...

オペレーターが知っておくべき 18 個の Nginx プロキシ キャッシュ構成のヒント (どれを知っていますか?)

アプリケーションや Web サイトのパフォーマンスが成功の重要な要素であることは誰もが知っています。...

WeChatアプレットが計算機機能を実装

WeChatミニプログラムはますます人気が高まっています。多くの大学生が独学で学んでいるのも見てきま...

Docker Consul コンテナ サービスの更新と見つかった問題の概要

目次1. コンテナサービスの更新とDockerコンサルの検出1. サービス登録と検出とは何ですか? ...

Centos7 での python3 のインストールとアンインストールに関するチュートリアル

1. Python 3をインストールする1. 依存パッケージをインストールしますyum instal...

(MariaDB) MySQL のデータ型とストレージメカニズムの包括的な説明

1.1 データ型の概要データ型は、各フィールドに保存できるデータの種類、保存できるデータの量、保存で...

ウェブページの再設計の7つの主要要素 ウェブページの再設計の7つの主要要素を共有する

Shopify Plus は、私たちが設立した e コマース プラットフォームのエンタープライズ バ...