javascript設計モードインタフェース紹介

6618 ワード

この本の中で一番重要な内容はインターフェースです.
みんなはインターフェースに慣れていないはずです.簡単にインターフェースは契約や規範です.強いタイプの面相オブジェクト言語では、インターフェースが簡単に実現できます.しかし、javascriptでは、オリジナルのインターフェースの作成や実現の方法がないか、あるいはあるインターフェースが実現されたかどうかを判定します.私たちはjsの柔軟性の特徴を利用して、アナログインターフェースしか利用できません.
javascriptでインターフェースを実現するには3つの方法があります.コメント記述、属性検証、アヒルの模型.
ノート:英語の本を読んでいますので、翻訳のレベルが限られています.一部の単語はどうやって翻訳するか分かりません.みんなは精神を理解するしかないです.
1.コメント記述(Describing Interfaces with Comments)
例:
 
  
/*
interface Composite {
  function add(child);
  function remove(child);
  function getChild(index);
}
interface FormItem {
  function save();
}
*/
var CompositeForm = function(id, method, action) { // implements Composite, FormItem
  ...
};
//Implement the Composite interface.
CompositeForm.prototype.add = function(child) {
...
};
CompositeForm.prototype.remove = function(child) {
...
};
CompositeForm.prototype.getChild = function(index) {
...
};
// Implement the FormItem interface.
CompositeForm.prototype.save = function() {
...
};
他の対象言語をシミュレートして、インタフェースとimplementsのキーワードを使っていますが、彼らを注釈する必要があります.そうすると、文法的な間違いがありません.
このようにする目的はただ他のプログラミングスタッフに教えるために、これらはどのような方法を実現する必要がありますか?しかし、これらのインターフェースの中の方法が正しく実現されているかどうかを検証する方法が提供されていません.この方法は文書化のやり方です.
2.属性検証(Emullating Interfaces with Attribute Checking)
例:
 
  
/* interface
Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
function save();
}
*/
var CompositeForm = function(id, method, action) {
this.implementsInterfaces = ['Composite', 'FormItem'];
...
};
...
function addForm(formInstance) {
if(!implements(formInstance, 'Composite', 'FormItem')) {
    throw new Error("Object does not implement a required interface.");
  }
  ...
}
// The implements function, which checks to see if an object declares that it
// implements the required interfaces.
function implements(object) {
  for(var i = 1; i < arguments.length; i++) {
    // Looping through all arguments
    // after the first one.
    var interfaceName = arguments[i];
    var interfaceFound = false;
    for(var j = 0; j < object.implementsInterfaces.length; j++) {
      if(object.implementsInterfaces[j] == interfaceName) {
        interfaceFound = true;
        break;
      }
    }
    if(!interfaceFound) {
      return false;
      // An interface was not found.
   }
  }
  return true;
// All interfaces were found.
}
このような方式は第一の方式より改善され、インターフェースの定義は依然として注釈の方式で実現されているが、検証方法を追加して、ある種類のインターフェースが実現されたかどうかを判断する.
3.アヒルタイプ(Emullating Interfaces with Duck Typeng)
 
  
// Interfaces.
var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
var FormItem = new Interface('FormItem', ['save']);
// CompositeForm class
var CompositeForm = function(id, method, action) {
  ...
};
...
function addForm(formInstance) {
  ensureImplements(formInstance, Composite, FormItem);
  // This function will throw an error if a required method is not implemented.
  ...
}
// Constructor.
var Interface = function(name, methods) {
  if(arguments.length != 2) {
    throw new Error("Interface constructor called with "
             + arguments.length + "arguments, but expected exactly 2.");
  }
  this.name = name;
  this.methods = [];
  for(var i = 0, len = methods.length; i < len; i++) {
    if(typeof methods[i] !== 'string') {
      throw new Error("Interface constructor expects method names to be "
              + "passed in as a string.");
    }
    this.methods.push(methods[i]);
  }
};
// Static class method.
Interface.ensureImplements = function(object) {
  if(arguments.length < 2) {
    throw new Error("Function Interface.ensureImplements called with "
              +arguments.length + "arguments, but expected at least 2.");
  }
for(var i = 1, len = arguments.length; i < len; i++) {
    var interface = arguments[i];
    if(interface.constructor !== Interface) {
      throw new Error("Function Interface.ensureImplements expects arguments"
              + "two and above to be instances of Interface.");
    }
    for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
      var method = interface.methods[j];
      if(!object[method] || typeof object[method] !== 'function') {
        throw new Error("Function Interface.ensureImplements: object "
                + "does not implement the " + interface.name + " interface. Method " + method + " was not found.");
      }
    }
  }
};
インターフェースはいつ使いますか?
多くのjavascriptプログラマーはもうインタフェースとインタフェースの検証がない状況で長年プログラミングしました.デザインモードで複雑なシステムを設計し始めると、インターフェースを使うほうがいいです.インターフェースはJavascriptの柔軟性を制限しているように見えますが、実は彼はあなたのコードをもっと緩く結合させます.彼はあなたのコードをより柔軟にしてくれます.どんな種類の変数でも送ることができます.多くのシーンのインターフェイスがとても使いやすいです.
大きなシステムの中で、多くのプログラマーが開発プロジェクトに参加します.インターフェースが必要になります.プログラマはしばしば、まだ実現されていないapiにアクセスしたり、他のプログラマに依存する方法の保存を提供したりする.この場合、インターフェースはかなり価値がある.彼らはアプリを文書化してプログラミングの契約をすることができます.根が実装されているアプリに置き換えられた場合、開発過程でapiが変動したら、他のインターフェースを実現する方法によってシームレスに置き換えられます.
インターフェースはどう使いますか?
まず解決したい問題は、あなたのコードの中でインターフェースを使うのに適していますか?小さい項目であれば、インターフェースを使うとコードの複雑さが増します.ですから、インタフェースを使う場合、メリットが弊害より大きいかどうかを確認してください.インターフェースを使うなら、以下のいくつかの提案があります.
1.Interface類をあなたのページファイルに引用します.interfaceのソースファイルは次のサイトで見つけられます.http://jsdesignpatterns.com/.
2.コードを確認して、どのような方法がインターフェースに抽象的に必要ですか?
3.インターフェースオブジェクトを作成して、インターフェースオブジェクトがない中に関連の方法が含まれています.
4.すべてのコンストラクタを除去して検証し、第三のインターフェースを使って実現します.つまりアヒルのタイプです.
5.コンストラクタの代わりにInterface.ensureImplementsで検証する.