2009-09-14 28 views
22

Ich nehme an, dies könnte für jede dynamische Sprache gelten, aber die, die ich verwende, ist JavaScript. Wir haben eine Situation, in der wir ein paar Steuerelemente in JavaScript schreiben, die eine Send() - Funktion bereitstellen müssen, die dann von der Seite aufgerufen wird, die das JavaScript hostet. Wir haben ein Array von Objekten, für die diese Sendefunktion definiert ist, so dass wir die Sammlung durchlaufen und Send() für jedes der Objekte aufrufen. Wenn Sie in einer OO-Sprache etwas Ähnliches tun möchten, verfügen Sie über eine IControl-Schnittstelle mit einer Send() - Funktion, die von jedem Steuerelement implementiert werden muss. Dann verfügen Sie über eine Sammlung von IControl-Implementierungen Sie würden durchlaufen und die Methode send aufrufen.Sind Schnittstellen in JavaScript notwendig?

Meine Frage ist, da JavaScript eine dynamische Sprache ist, muss man eine Schnittstelle definieren, von der die Steuerelemente erben sollen, oder ist es gut genug, nur die Send() Funktion auf den Steuerelementen aufzurufen?

+4

Ich liebe dein Gravatar :) – alex

Antwort

10

Dynamische Sprachen ermutigen oft Duck Typing, in denen Methoden des Objekts diktieren, wie es verwendet werden sollte, anstatt einen expliziten Vertrag (z. B. eine Schnittstelle).

+34

Ich glaube nicht, dass Schnittstellen sind im Gegensatz zum Tippen von Enten. Ganz im Gegenteil, eigentlich. Wenn Sie eine Schnittstelle deklarieren, können Sie eine klare Aussage darüber haben, welche Methoden Sie aufrufen möchten. Oft habe ich Methoden gefunden, die Objekte akzeptieren, die z. B. dateiartig sind, ohne dass ein deutlicher Hinweis darauf vorhanden ist, was ein dateiähnliches Objekt implementieren soll. Ist read() und close() genug? Brauche ich auch suchen()? Was ist mit write()? Schnittstellen sind eine klare und eindeutige Möglichkeit, um Ihre Bedürfnisse zu definieren, und als solche sind eine große Verbesserung ** vor allem ** wenn Sie sich auf die Eingabe von Ente verlassen wollen – Andrea

+2

Auch die Möglichkeit, Ad-hoc-Schnittstellen, die einfach erklärt, welche Methoden und Mitglieder ein Parameter sollte hätte nützlich sein. Es muss keine benannte Schnittstelle sein - nur eine Wertbeschränkung. –

4

Da Sie jede Methode für jedes Objekt in einer dynamischen Sprache aufrufen können, bin ich mir nicht sicher, wie die Schnittstellen auf wirklich nützliche Weise ins Spiel kommen würden. Es gibt keine Verträge, die durchgesetzt werden müssen, weil alles zum Zeitpunkt des Aufrufs festgelegt wird - ein Objekt könnte sogar ändern, ob es über seine Lebensdauer einem "Vertrag" entspricht, da Methoden während der Laufzeit hinzugefügt und entfernt werden. Der Anruf wird fehlschlagen, wenn das Objekt einen Vertrag nicht erfüllt, oder es wird fehlschlagen, wenn es kein Mitglied implementiert - beide Fälle sind für die meisten praktischen Zwecke identisch.

+0

Es gibt eine [Knol] (http://web.archive.org /web/20120416022026/http://knol.google.com/k/programming-to-the-interface-in-javascript-ja-es-kann-getan-er-ich-gemein-gefälscht #) (ja knol) zu diesem Thema – bobobobo

3

Dies ist das gleiche für PHP; Sie brauchen keine Schnittstellen. Aber sie existieren für architektonische Bedürfnisse. In PHP können Sie Typhinweise für Funktionen angeben, die nützlich sein können.

Zweitens ist eine Schnittstelle ein Vertrag. Es ist ein formeller Vertrag, dass alle Objekte von dieser Schnittstelle haben diese Funktionen. Besser, um sicherzustellen, dass Ihre Klassen diese Anforderungen erfüllen, als sich zu erinnern: "mm, diese Klasse hat isEnabled(), aber die andere ist checkIfEnabled()". Schnittstellen helfen Ihnen bei der Standardisierung. Andere, die an dem abgeleiteten Objekt arbeiten, müssen nicht überprüfen, ob der Name isEnabled oder checkIfEnabled lautet (besser, dass der Interpreter diese Probleme bemerkt).

2

Wir sahen eine schöne Umsetzung auf der Seite unten, das ist unsere (kurze Version davon)

var Interface = function (methods) { 
    var self = this; 
    self.methods = []; 

    for (var i = 0, len = methods.length; i < len; i++) { 
     self.methods.push(methods[i]); 
    } 

    this.implementedBy = function (object) { 

     for (var j = 0, methodsLen = self.methods.length; j < methodsLen; j++) { 
      var method = self.methods[j]; 
      if (!object[method] || typeof object[method] !== 'function') { 
       return false; 
      } 
     } 
     return true; 
    } 
}; 

//Call 
var IWorkflow = new Interface(['start', 'getSteps', 'end']); 
if (IWorkflow.implementedBy(currentWorkFlow)) { 
    currentWorkFlow.start(model); 
} 

Das ganze Beispiel ist: http://www.javascriptbank.com/how-implement-interfaces-in-javascript.html

0

Eine weitere Alternative zu den Schnittstellen von Angeboten bob.js:

1. überprüfen Sie, ob die Schnittstelle implementiert:

var iFace = { say: function() { }, write: function() { } }; 
var obj1 = { say: function() { }, write: function() { }, read: function() { } }; 
var obj2 = { say: function() { }, read: function() { } }; 
console.log('1: ' + bob.obj.canExtractInterface(obj1, iFace)); 
console.log('2: ' + bob.obj.canExtractInterface(obj2, iFace)); 
// Output: 
// 1: true 
// 2: false 

2. Extract Schnittstelle aus dem Objekt und führen immer noch die Funktionen richtig:

var obj = { 
    msgCount: 0, 
    say: function (msg) { console.log(++this.msgCount + ': ' + msg); }, 
    sum: function (a, b) { console.log(a + b); } 
}; 
var iFace = { say: function() { } }; 
obj = bob.obj.extractInterface(obj, iFace); 
obj.say('Hello!'); 
obj.say('How is your day?'); 
obj.say('Good bye!'); 
// Output: 
// 1: Hello! 
// 2: How is your day? 
// 3: Good bye! 
Verwandte Themen