Нужны ли интерфейсы в JavaScript? - PullRequest
22 голосов
/ 14 сентября 2009

Полагаю, это может относиться к любому динамическому языку, но я использую JavaScript. У нас есть ситуация, когда мы пишем пару элементов управления в JavaScript, которые должны предоставить функцию Send (), которая затем вызывается страницей, на которой размещен JavaScript. У нас есть массив объектов, для которых определена эта функция Send, поэтому мы перебираем коллекцию и вызываем Send () для каждого из объектов.

В языке OO, если вы хотите сделать что-то подобное, у вас будет интерфейс IControl с функцией Send (), который должен быть реализован каждым элементом управления, а затем у вас будет набор реализаций IControl, которые вы перебрать и вызвать метод send.

У меня такой вопрос, поскольку JavaScript является динамическим языком. Есть ли необходимость в определении интерфейса, от которого должны наследоваться элементы управления, или это достаточно хорошо, чтобы просто вызывать функцию Send (), доступную для элементов управления?

Ответы [ 5 ]

10 голосов
/ 14 сентября 2009

Динамические языки часто поощряют Duck Typing , в котором методы объекта определяют способ его использования, а не явный контракт (например, интерфейс).

4 голосов
/ 14 сентября 2009

Поскольку вы можете вызывать любой метод для любого объекта на динамическом языке, я не уверен, каким образом интерфейсы будут задействованы каким-либо действительно полезным способом. Не существует контрактов для принудительного исполнения, потому что все определяется во время вызова - объект может даже измениться, соответствует ли он «контракту» в течение его жизни, поскольку методы добавляются и удаляются во время выполнения. Вызов завершится ошибкой, если объект не выполнит контракт, или произойдет сбой, если он не реализует член - в большинстве случаев тот же случай для большинства практических целей.

3 голосов
/ 14 сентября 2009

Это то же самое для PHP; вам не нужны интерфейсы. Но они существуют для архитектурных нужд. В PHP вы можете указать подсказки типов для функций, которые могут быть полезны.

Во-вторых, интерфейс - это контракт. Это официальный контракт, согласно которому все объекты этого интерфейса имеют эти функции . Лучше убедиться, что ваши классы соответствуют этим требованиям, чем помнить: « мм, этот класс имеет isEnabled(), а другой - checkIfEnabled()». Интерфейсы помогут вам стандартизировать. Другие, работающие с производным объектом, не должны проверять, является ли имя isEnabled или checkIfEnabled (лучше, чтобы интерпретатор уловил эти проблемы).

2 голосов
/ 18 сентября 2012

Мы увидели хорошую реализацию на странице ниже, это наша (короткая версия)

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);
}

Весь пример по адресу: http://www.javascriptbank.com/how-implement-interfaces-in-javascript.html

0 голосов
/ 04 апреля 2013

Другая альтернатива интерфейсам предлагается bob.js :

1. Проверьте, реализован ли интерфейс:

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. Извлеките интерфейс из объекта и по-прежнему выполняйте функции должным образом:

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! 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...