ホームページ  >  記事  >  ウェブフロントエンド  >  JS の一般的なデザイン パターン

JS の一般的なデザイン パターン

小云云
小云云オリジナル
2018-02-23 15:14:221469ブラウズ

大規模なシングルページアプリケーションでは、複雑さが一定レベルに達すると、デカップリングに適した設計パターンがなく、その後の開発の開始が困難になります。
デザインパターンはまさにデカップリングのために存在します。

シングルトン パターン

シングルトン パターンの中核は、インスタンスが 1 つだけ存在することを保証し、グローバル アクセスを提供することです。

特徴

「単一責任の原則」を満たす: プロキシモードを使用すると、シングルトンが作成されたかどうかはコンストラクターで判断されません

遅延の原則を満たす

アプリケーション

はログインウィンドウをポップアップします。 。

インスタンス

 var getSingle = function (fn) {
    var res;
    return function() {
        return res || (res = fn.apply(this, arguments));
    }
}

var createPopup() {
    var p = document.createElement('p');
    p.innerHTML = "Login window";
    p.style.display = "none"; 
    document.body.appendChild(p);
    return p;
}

var createLoginPopup = getSingle(createPopup);            
//create popup p here by using a given function, 满足两个原则 

document.getElementById("loginBt").onclick = function() {
    var popup = createLoginPopup();
    pop.style.display = "block";
}

コンストラクターモード

/**
 * 构造一个动物的函数 
 */
function Animal(name, color){
    this.name = name;
    this.color = color;
    this.getName = function(){
        return this.name;
    }
}
// 实例一个对象
var cat = new Animal('猫', '白色');
console.log( cat.getName() );

プロトタイプモード

function Person(){  
}

Person.prototype.name = "bill";
Person.prototype.address = "GuangZhou";
Person.sayName = function (){
    alert(this.name);  
}

var person1 = new Person();
var person2 = new Person();
 
//测试代码
alert(person1.name);   // bill
alert(person2.name);    // bill
person1.sayName();    //bill
person2.sayName();    //bill

person1.name = "666";

alert(person1.name);   // 666
alert(person2.name);    // bill
person1.sayName();    //666
person2.sayName();    //bill

混合モード

/**
 * 混合模式 = 原型模式 + 构造函数模式
 */
function Animal(name, color){
    this.name = name;
    this.color = color;

    console.log( this.name  +  this.color)
}
Animal.prototype.getInfo = function(){
    console.log('名称:'+ this.name);
}

function largeCat(name, color){
    Animal.call(null, name, color);

    this.color = color;
}

largeCat.prototype = create(Animal.prototype);
function create (parentObj){
    function F(){}
    F.prototype = parentObj;
    return new F();
};

largeCat.prototype.getColor = function(){
    return this.color;
}
var cat = new largeCat("Persian", "白色");
console.log( cat )

ファクトリーモード

ファクトリー: b オブジェクトは関数によって内部的に生成され、返されます。

1. 
function a(name){
  var b = new object();
    b.name = name;
    b.say = function(){
        alert(this.name);
    }   
       return b    
}
2. 
function Animal(opts){
    var obj = new Object();
    obj.name = opts.name;
    obj.color = opts.color;
    obj.getInfo = function(){
        return '名称:'+obj.name +', 颜色:'+ obj.color;
    }
    return obj;
}
var cat = Animal({name: '波斯猫', color: '白色'});
cat.getInfo();

シンプルなファクトリ パターン

シンプルなファクトリ パターンの考え方は、オブジェクトを作成し、さまざまなクラスをインスタンス化するだけで済みます。その後、このオブジェクトに対して多数のメソッドとプロパティを使用し、最後に戻り値を返します。オブジェクト

//basketball base class  
var Baseketball = function(){  
  this.intro = 'baseketball is hotting at unitedstates';  
}  
Baseketball.prototype = {  
  getMember : function(){\  
    console.log('each team needs five players');  
  },  
  getBallSize : function(){  
    console.log('basketball is big');  
  }  
}  
//football base class   
var Football = function(){  
  this.intro = 'football is popular at all of the world';  
}  
Football = function(){  
  getMember = function(){  
  
  },  
  getBallSize = function(){  
  
  }  
}  
//sport factory  
var SportsFactory = function(name){  
  switch(name){  
    case 'NBA':  
      return new Baseketball();  
    case 'wordCup':  
      return new Football();  
  }  
}  
  
//when you want football   
var football = SportsFactory('wordCup');  
console.log(football);  
console.log(football.intro);  
football.getMember();

イテレータパターン

デコレータパターン

戦略パターン

相互に交換可能なアルゴリズムを定義し、それらをカプセル化します。

機能

  1. オープンクローズ原則に従う: 使用するアルゴリズムを変更する場合、関数を深く変更する必要はなく、ストラテジー クラスを変更するだけで済みます。

  2. アルゴリズムの再利用性を向上させるために、アルゴリズムの実装と使用を分離します。;
  3. 合成、委任、ポリモーフィズムによる複数の条件付き選択ステートメントを回避します。

アニメーションを適用して、さまざまなイージング効果を実現します。

大きく分けて戦略型と環境型の2つに分かれます。戦略クラスはさまざまなアルゴリズムをカプセル化するために使用され、特定の計算プロセスを担当します。環境クラスはユーザーのリクエストを受信し、そのリクエストを特定の戦略クラスに委託します。各戦略クラスで実装されるアルゴリズムや計算結果は異なりますが、環境クラスによる戦略クラスの呼び出し方法は同じであるため、これはポリモーフィズムを反映しています。さまざまなアルゴリズムを実装するには、環境クラスの戦略クラスを置き換えるだけで済みます。

js では、ストラテジー クラスを構築する必要はなく、関数をストラテジー オブジェクトとして直接使用できます。

var strategies = {
    "s1": function() {
        //algo 1
    },
    "s2": function() {
        //algo 2
    }, 
    "s3": function() {
        //algo 3
    }
 }
 
 var someContext =  new SomeConext();
 someContext.start("s1");  //using s1 to calculate
 //someContext.add("s1");  or add s1 as a rule for validation

外観モード

は、ファサードモードとも訳せます。 Facade パターンは、サブシステム内の一連のインターフェイスに一貫したインターフェイスを提供し、このサブシステムを使いやすくする高レベルのインターフェイスを定義します。外観ロールの導入後、ユーザーは外観ロールと直接対話するだけで済み、ユーザーとサブシステム間の複雑な関係が外観ロールによって実現されるため、システムの結合が軽減されます。

例えば、家で映画を見たい場合は、ステレオの電源を入れ、次にプロジェクターの電源を入れ、次にプレーヤーの電源を入れるなどの操作が必要です。 登場キャラクターを紹介した後、「開く」を呼び出すだけで済みます。ムービーデバイス」の方法です。アピアランス ロールは、プロジェクターを開くなどの操作をカプセル化し、ユーザーに使いやすい方法を提供します。


関数

    複雑なインターフェースを簡素化
  1. ユーザーをサブシステムへの直接アクセスから切り離しシールドする
  2. インスタンス

JavaScriptの形式では、外観パターンは次のようになります:

function a(x){
   // do something
}
function b(y){
   // do something
}
function ab( x, y ){
    a(x);
    b(y);
}

次の例では、ブロックを配置します。外観ロールへのデフォルトイベントのバブリングとブロック:

var N = window.N || {};

N.tools = {
    stopPropagation : function( e ){
        if( e.stopPropagation ){
            e.stopPropagation();
        }else{
            e.cancelBubble = true;
        }
    },

    preventDefault : function( e ){
        if( e.preventDefault ){
            e.preventDefault();
        }else{
            e.returnValue = false;
        }
    },
    
    stopEvent : function( e ){
        N.tools.stopPropagation( e );
        N.tools.preventDefault( e );
    }

JavaScript での外観モードの適用は、主に 2 つのカテゴリに分類できます。たとえば、関数 a の呼び出しは、基本的に関数を呼び出す前に繰り返し表示されます。 b、構造を最適化するために、このコード部分を外観ロールでラップすることを検討できます。もう 1 つの方法は、一部のブラウザと互換性のない API を外観内に配置して判断することです。これらの問題に対処する最善の方法は、ブラウザ間の違いをすべて外観モード インスタンスに集中させて外部インターフェイスを提供することです。

プロキシ パターン

プロキシ パターンの定義: このオブジェクトへのアクセスを制御するために、他のオブジェクトにプロキシを提供します。場合によっては、あるオブジェクトが適切でないか、別のオブジェクトを直接参照できない場合、プロキシ オブジェクトがクライアントとターゲット オブジェクトの間の仲介者として機能することがあります。

仮想プロキシ

仮想プロキシは、実際に必要になるまで一部の高価なオブジェクトの作成と実行を遅らせます

画像の遅延読み込み

//图片加载
let imageEle = (function(){
    let node = document.createElement('img');
    document.body.appendChild(node);
    return {
        setSrc:function(src){
            node.src = src;
        }
    }
})();

//代理对象
let proxy = (function(){
    let img = new Image();
    img.onload = function(){
        imageEle.setSrc(this.src);
    };
    return {
        setSrc:function(src){
            img.src = src;
            imageEle.setSrc('loading.gif');
        }
    }
})();

proxy.setSrc('example.png');

httpリクエストをマージします

頻繁なリクエスト操作を必要とする機能がある場合、これは比較的高価ですが、プロキシ機能を通じて一定期間内のリクエストデータを収集し、一度送信できます 受信パラメータが以前と同じ場合、以前に保存された操作結果を直接返すことができます

//上传请求
let upload = function(ids){
    $.ajax({
        data: {
            id:ids
        }
    })
}

//代理合并请求
let proxy = (function(){
    let cache = [],
        timer = null;
    return function(id){
        cache[cache.length] = id;
        if(timer) return false;
        timer = setTimeout(function(){
            upload(cache.join(','));
            clearTimeout(timer);
            timer = null;
            cache = [];
        },2000);
    }    
})();
// 绑定点击事件
let checkbox = document.getElementsByTagName( "input" );
for(var i= 0, c; c = checkbox[i++];){
    c.onclick = function(){
        if(this.checked === true){
            proxy(this.id);
        }
    }
}

メリットとデメリット

1. 利点: プロキシ モードでは、プロキシ オブジェクトを呼び出されたオブジェクトから分離できるため、システムの結合が軽減されます。プロキシ モードは、クライアントとターゲット オブジェクトの間の仲介的な役割を果たし、ターゲット オブジェクトを保護できます。プロキシ オブジェクトは、ターゲット オブジェクトを呼び出す前に他の操作を実行することもできます。

2. デメリット: システムの複雑さが増す

オブザーバーパターン

モジュールパターン

//计算乘积
let mult = function(){
    let result = 1;
    for(let i = 0,len = arguments.length;i < len;i++){
        result*= arguments[i];
    }
    return result;
}

//缓存代理
let proxy = (function(){
    let cache = {};
    reutrn function(){
        let args = Array.prototype.join.call(arguments,',');
        if(args in cache){
            return cache[args];
        }
        return cache[args] = mult.apply(this,arguments);
    }
})();

関連する推奨事項:

js 組み合わせ設計パターンの詳細な説明

PHPデザインパターンのサービスロケーターパターン例の詳細説明

PHPデザインパターンのデリゲーションパターンの詳細説明

以上がJS の一般的なデザイン パターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。