定義
Decoratorパターンは、オブジェクトが動的な機能を追加するために、プログラムの実行ターゲットの間に、自分自身に基づいて変更することができます。
あなたは、時間のDecoratorパターンの定義を参照すると、三の大特性の我々が考えるJSの1 - 継承は、それが責任の追加ダイナミックに基づいて、オブジェクト自体を変更せずに達成するだけでなく、実現可能なことができていません。なぜそれがここでDecoratorパターンを必要とするのか?この問題を解決する前に、我々は、継承の概念について話すだろう。
受け継ぎます
プログラミングは人間の心に近づくように継承は、コードの再利用の問題を解決することができます。同じクラスの存在複数の属性(変数)及び方法は、これらのクラスの親クラスから抽出することができる場合、親クラスで定義されたこれらの同じプロパティとメソッド、これらのプロパティおよびメソッドを再定義することなくすべてのサブクラス、親クラスから継承されたプロパティとメソッドを介してのみ。
JSの継承方法:ここではいくつかの一般的な継承されています
1.オブジェクトのポーズは:オブジェクトは、そのクラス、メソッド呼び出しのjsのすべてのメンバーを意味するふり得ることです、あなたはその方法の全てを取得します。
// 对象冒充 機能の父親(名前、年齢){ この .nameの= 名前 この .age = 年齢 この .SHOW = 機能(){ はconsole.log(' 我叫' + この .nameの、' 今年' + この.age ) } } 関数の息子(名前、年齢){ この .father = 父 本.father(名前、年齢) この .showSon = 関数(){ にconsole.log(' 自己' ) } } 息子のlet = 新しい新しい息子(' GMN '、18 ) Son.show()//私は今年GMN 18です
2.プロトタイプチェーンの継承:プロトタイプのサブクラスとして親クラスのインスタンス
// 原型链继承 機能父(){ } Father.prototype.name = 関数(名前){ この .nameの= 名前 はconsole.log(' 名前' 、名前) } Father.prototype.age = 関数(年齢){ この .age = 年齢 } 機能の息子(){ } Son.prototype = 新しい父() Son.prototype.name(' GMN ')// GMN
特徴:
- 非常に純粋な継承は、インスタンスは、親クラスのインスタンスとしてだけでなく、サブクラスのインスタンスであります
- 親新しいプロトタイピング/ prototypeプロパティ、サブクラスは、にアクセスすることができます
- 実装がシンプルで、簡単に
短所:
- サブクラスのプロパティとメソッドを追加するには、でなければなりません
new Animal()
、このような文は、コンストラクタを置くことはできません後に実行 - 多重継承を達成することができません
- プロトタイプオブジェクトからすべてのプロパティは、すべてのインスタンスで共有されます
- あなたは、サブクラスのインスタンスを作成する場合、親クラスのコンストラクタにパラメータを渡すことはできません
ES6でも拡張し、クラス継承する必要があります。実際には、本質的には、プロトタイプベースのメカニズムです。
実際には、継承するいくつかの欠点があります。
1.強い結合サブクラススーパー、変化スーパー変化の結果をサブクラス
サブクラスブレークカプセルに見える2.スーパークラス内部の詳細
3.サブカテゴリーの多数を作成することができ、同時に多重化機能を実行します。
欠点の、唯一のDecoratorパターンを継承したので、それもあります。ホームへクローサー一時的にそんなに話を置くために、継承の概念は、Decoratorパターンを言うようになりました。
例:
オブジェクト指向言語の1伝統的な実装
//元のクラス
のvarオリジナル= 関数(){ }; Original.prototype.fire = 関数(){ にconsole.log(' 火' ); }; // 装飾 するvar MissileDecorator = 機能(計画){ この .planの= プラン; } MissileDecorator.prototype.fire = 関数(){ この.plan.fire() はconsole.log(' 実火' ); }; VARのプラン= 新しい新しい(オリジナル); プラン = 新しい新MissileDecorator(プラン); plan.fire(); // 火 // 本当に火に
これを達成する方法は、部屋のデコレータクラスは、ターゲットオブジェクトへの参照を維持するために、また、すべての新しいインターフェイスああああターゲットクラスです。あなたがメソッド、メソッドを既存のターゲットオブジェクトの最初の実装を呼び出すと、自分自身の実装でプロパティを追加します。
2.JSオブジェクトベースの実装
VARオリジナル= { 火災:関数(){ にconsole.log(' 火' ); } }; VARの missileDecorator = 関数(){ にconsole.log(' 実際の火災' ); }; VARの火災= Original.fire ; Original.fire = 関数(){ 炎(); missileDecorator(); }; Original.fire(); // 火災 // 真火
デコレータは、別のオブジェクトにオブジェクトを埋め込む、別の目的は、包装された形態としてストランドパッケージと実際同等です。オブジェクトのすべてをお届けするために、この要求包装チェーンでは、それぞれがこの要求に対処するための機会を持っています。
図3は、Decoratorパターンのチェックを使用して実装してフォームを送信:機能は、パターンと提出され単離された形態の検証で飾ら
= Function.prototype.beforeの機能(beforefn){ VARの _this = この ; // 関数への古い参照保存 リターン機能(){ // 新しい機能や古い「エージェント」の機能を返しますが機能 beforefn.apply(この、引数) ; // 新しい関数は引数を受け入れ、新しい機能を実行し、これがハイジャックされないことを保証するために //が古い機能はそのままで通過します、新しい関数は古い関数の前に実行され 、戻り _this.apply(この、引数); }; }; VARの validata = 関数(){ IF(username.value === '' ){ アラート('ユーザー名は空にすることはできません!' ) に戻る falseに; } IF(password.value === ' ' ){ アラート(' パスワードを空にすることはできません!" ) に戻る falseに; } } VAR FORMSUBMIT = 機能(){ VARの PARAM = { ユーザ名 = username.value; パスワード = password.value; } アヤックス(' POST '、' http://www.mn.com ' 、のparam); } FORMSUBMIT = formSubmit.before(validata)。 submitBtn.onclick = 関数(){ FORMSUBMIT()。 }
概要
それが望まれる場合Decoratorパターンは、従って、それぞれ別々の機能に装飾されるべき機能の動的な機能をより多くの機能を追加する方法であり、次いで装飾の機能を既存のすべての機能をパッキングコードを呼び出す、特別なアクションを実行すると、オブジェクトをラップする装飾機能の使用の順序に従って、必要に応じて選択することができます。コアの責任と装飾的な特徴は区別のようなもの(機能)の利点