Почему большинство системных архитекторов настаивают на первом программировании интерфейса? - PullRequest
25 голосов
/ 07 сентября 2008

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

Однако всякий раз, когда я вижу, как архитекторы разрабатывают приложение, первое, что они делают, - это начинают программирование интерфейса. Как так? Как вы знаете все отношения между объектами, которые будут происходить в этом интерфейсе? Если вы уже знаете эти отношения, то почему бы просто не расширить абстрактный класс?

Ответы [ 16 ]

1 голос
/ 10 ноября 2008

Почему простирается зло . Эта статья является прямым ответом на заданный вопрос. Я не могу представить себе почти ни одного случая, когда вам действительно понадобится абстрактный класс, и множество ситуаций, когда это плохая идея. Это не означает, что реализации, использующие абстрактные классы, являются плохими, но вам придется позаботиться о том, чтобы не сделать контракт интерфейса зависимым от артефактов какой-то конкретной реализации (пример: класс Stack в Java).

Еще одна вещь: нет необходимости или хорошей практики иметь интерфейсы везде. Как правило, вы должны определить, когда вам нужен интерфейс, а когда нет. В идеальном мире второй случай должен быть реализован как финальный класс большую часть времени.

0 голосов
/ 02 января 2010

Я думаю, что основной причиной использования интерфейсов в Java является ограничение одиночного наследования. Во многих случаях это приводит к ненужным усложнениям и дублированию кода. Посмотрите на Черты в Scala: http://www.scala -lang.org / node / 126 Черты - это особый вид абстрактных классов, но класс может расширять многие из них.

0 голосов
/ 22 января 2009

Вы можете увидеть это с точки зрения perl / python / ruby:

  • когда вы передаете объект в качестве параметра методу, который не передает его тип, вы просто знаете, что он должен реагировать на некоторые методы

Я думаю, что рассмотрение интерфейсов java как аналогии с этим лучше всего объясняет это. Вы действительно не передаете тип, вы просто передаете что-то, что отвечает методу (черта, если хотите).

0 голосов
/ 15 декабря 2008

Все дело в проектировании до кодирования.

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

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

0 голосов
/ 09 ноября 2008

Одна из причин заключается в том, что интерфейсы обеспечивают рост и расширяемость. Скажем, например, что у вас есть метод, который принимает объект в качестве параметра,

общедоступный напиток (кофе иногда пьют) {

}

Теперь предположим, что вы хотите использовать точно такой же метод, но передать объект hotTea. Ну, ты не можешь. Вы просто жестко запрограммировали этот метод, чтобы использовать только кофейные объекты. Может быть, это хорошо, может быть, это плохо. Недостатком вышесказанного является то, что он строго блокирует вас одним типом объекта, когда вы хотите передать все виды связанных объектов.

Используя интерфейс, скажем, IHotDrink,

интерфейс IHotDrink {}

и переписать вышеописанный метод для использования интерфейса вместо объекта,

общественный пустой напиток (IHotDrink someDrink) {

}

Теперь вы можете передавать все объекты, которые реализуют интерфейс IHotDrink. Конечно, вы можете написать точно такой же метод, который делает то же самое с другим параметром объекта, но почему? Вы вдруг поддерживаете раздутый код.

0 голосов
/ 07 сентября 2008

В некотором смысле, я думаю, что ваш вопрос сводится к простому: «зачем использовать интерфейсы, а не абстрактные классы?» Технически, вы можете добиться слабой связи с обоими - базовая реализация по-прежнему не доступна вызывающему коду, и вы можете использовать шаблон Abstract Factory для возврата базовой реализации (реализация интерфейса или расширение абстрактного класса), чтобы увеличить гибкость вашей дизайн. Фактически, вы можете утверждать, что абстрактные классы дают вам немного больше, поскольку они позволяют вам требовать реализации, чтобы удовлетворить ваш код («вы ДОЛЖНЫ реализовывать start ()»), и предоставлять реализации по умолчанию («у меня есть стандартная paint (), которую вы можно переопределить, если хотите ") - с интерфейсами должны быть обеспечены реализации, которые со временем могут привести к хрупким проблемам наследования из-за изменений интерфейса.

По сути, я использую интерфейсы в основном из-за ограничения одиночного наследования Java. Если моя реализация ДОЛЖНА наследоваться от абстрактного класса, который будет использоваться при вызове кода, это означает, что я теряю гибкость, чтобы наследовать от чего-то другого, даже если это может иметь больше смысла (например, для повторного использования кода или иерархии объектов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...