Интерфейсы Java - Что именно в контракте?

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

Поэтому, когда я создаю реализацию, я должен выполнить контракт. Мои вопросы: что именно в том контракте, который я должен выполнить?

Очевидно, что как минимум вы должны предоставить методы с теми же сигнатурами, что и интерфейс. Код не будет компилироваться иначе. Это все "контракт" влечет за собой? Кажется, что должно быть больше.

Например, я читал статьи, в которых обсуждается важность тестирования интерфейса или тестирования конкретных реализаций или выполнения обоих. Я вижу большую ценность в том, чтобы иметь тесты для интерфейса, чтобы вы знали, какие входы имеют ожидаемые результаты. Мне кажется, что это также будет частью интерфейса "контракт". Каждая реализация интерфейса должна создавать одинаковые выходные данные с одинаковых входных данных. Очевидно, что в коде нет способа обеспечить выполнение этого контракта, но его можно реализовать с помощью контрольных примеров. Я ошибаюсь в своем мышлении здесь?

Наконец, как насчет побочных эффектов, которые имеют реализации? Здесь я в основном говорю о любой настойчивости, которая может произойти как часть реализации. Скажем, у меня есть реализация, которая сохраняет некоторые записи в БД во время выполнения операции. Будет ли это как-то частью интерфейса "контракт"? Если так, как вы могли бы обеспечить соблюдение этого контракта? На уровне интерфейса я понятия не имею, что на самом деле делает реализация. Все, что я знаю, это то, что я даю ему входные данные, и он дает мне выходные данные, которые я могу проверить. Любая настойчивость, которая случается, также считается "результатом"? Если так, я просто не вижу, как это можно проверить и применить. Я сторонник постоянного невежества, поэтому я мог знать, что что-то должно сохраняться, но я не знаю, как оно сохраняется. Так что я просто не знаю как сказать, когда что-то действительно сохранилось. Это может быть просто, если ваш интерфейс имеет несколько простых операций CRUD, но я хочу подумать о более сложных интерфейсах.

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

3 ответа

Я думаю, что у "контракта" и "интерфейса" очень мало общего.

Интерфейс - это что-то вроде двери. Дверь может проходить обычного человека, но не слонов, жирафов или автомобилей.

Контракт - это когда вы можете быть уверены, что через дверь придет только женщина, или мужчина, или разработчик программного обеспечения.

Таким образом, контракт определяет поведение, а интерфейс определяет, какая информация передается

Я думаю, что вы заключаете слишком большую сделку по поводу термина "контракт".

" Эйфелева " имеет очень специфическую философию "дизайн по контракту". Лично я думаю, что другие языки выиграют от чего-то подобного.

Неформально вы, конечно, можете думать о "интерфейсах" Java как о "контракте". Ваше определение интерфейса Java, безусловно, хорошо:

как минимум, вы должны предоставить методы с теми же сигнатурами, что и интерфейс. Код не будет компилироваться иначе.

Q: Это все "контракт" влечет за собой?

A: Вероятно, нет. Все зависит от того, как вы определяете "контракт";)

Но, IMHO, интерфейсы Java являются гораздо более чистой функцией, чем ужас C++ "множественное наследование". И одна из основных мотивов поддержки обоих заключается в поддержке " миксинов ":

Точно так же Java-интерфейсы также предоставляют чистое, относительно простое решение с сохранением типов для поддержки " обратных вызовов ".

Последнее предложение: пожалуйста, обратите внимание на разницу между "интерфейсом" и "абстрактным классом". Это также может дать вам дополнительное представление об интерфейсах Java и о том, как вы можете эффективно использовать их в своем собственном коде:

Интерфейс против абстрактного класса (общий ОО)

Таким образом, контракт - это сигнатура метода + любая документация, связанная с функцией / классом. Вывод из этого заключается в том, что интерфейс не означает то же самое, что ключевое слово java interface, Интерфейс - это все, что позволяет вам взаимодействовать с другой системой. Итак, к вопросу о том, как вы выполняете контракт функции, объявленной так:

    /**  Throws IllegalArgumentException if s is null.    
Converts the input <b>s</b> into an {@link Integer}  */
    function go(String s);

Вам нужно написать следующую реализацию:

function go(String s)  
{  
    if(null == s) throw new IllegalArgumentException();  
    int i = Integer.parseInt(s);
}  

Придумано да, но это должно объяснить, как выполнить контракт и соблюдать его.

Другие вопросы по тегам