Нужны ли интерфейсы в JavaScript?

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

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

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

5 ответов

Решение

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

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

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

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

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

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

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! 
Другие вопросы по тегам