Здравствуйте, rsn81, Вы писали:
R>Почти дословно с главой из GoF "Программирование в соответствие с интерфейсом, а не реализацией"; вначале показалось, сверил с книгой — действительно.
Читал GoF последний раз лет 5 назад, так что все совпадения случайны

... << RSDN@Home 1.2.0 alpha rev. 716>>
Здравствуйте, busk, Вы писали:
B>люди подскажите. пишу класс для работы с БД. везде прочитал что в таких ситуациях лучше использовать интерфейс, а от него уже отнаследовать класс и в нем реализовать функции интерфейса.
B>Вопрос: для чего нужен интерфейс, если у меня будет всего один класс отнаследован от него и все функции я могу вынести просто в сам класс по работе с БД.
B>p.s. Если интерфейс здесь все таки не нужен то в каких практических задачах их используют?
"Чистое" ООП предполагает, что есть некоторая среда, в которой существуют объекты и эти объекты обмениваются между собой сообщениеями. По сути, оно так и есть в динамических ООЯ (или, как их называют в народе, прототип-ориентированных языках). Конечно, такой подход очень гибок, даже слишком гибок и часто эта гибкость нужна как собаке пятая нога. А, между тем, он обладает рядом недостатков. В частности, программы на прототип-ориентированных языках тяжелее отлаживать: можно банально ошибиться в названии сообщения при наборе текста и эта ошибка выявится только тогда, когда это сообщение реально будет послано в рантайме. А почему бы нам не заставить компьютер следить за правильностью программы? В таком виде это сделать невозможно, но можно для компьютера в программе оставить предписания, какой объект какие сообщения может обрабатывать, чтобы нас ударил по рукам компилятор. Такой подход вводит некоторые ограничения, но это не смертельно, к тому же многие ограничения (если это действительно необходимо!) обходятсяс помощью всяких RTTI и Reflection.
Собственно, интерфейс и является этим самым предписанием для компилятора. Но это пока ничего не говорит, потому нужно некая связка с тем, что и так хорошо известно программистам на C++/Java/C#. А им, как раз, хорошо известны классы. Так вот, на самом деле, классы в таких языках являются не классами, а паттернами для одновременного описания интерфейса, и класса, этот интерфейс реализующего! Все public-члены класса являются членами некоторого "анонимного" интерфейса, причём для них тут же даётся доп. реализация. Это, своего рода синтаксический сахар (на самом деле, в отстутсвии extenstion-методов это не совсем так). По идее, можно вообще обойтись без наследования классов, а ограничиться только наследованием интерфейсов и реализацией интерфейсов в классах.
Интерфейс нужен для того, чтобы от объекта можно было ожидать определённого поведения. Например, розетка ожидает от объекта, что он потребляет перменный ток 220 вольт, с частотой 50Гц, и что у объекта есть два штырька определённых размеров. Потому, любой объект, потребляющий электричество таким способом, должен реализовывать интерфейс IВилка. Розетку при этом вобще не интересует, что и как делает прибор, ей важен только один аспект функционирования прибора — потребление питания. Другой пример: человек ожидает от объекта, что он покажет ему фильм. Потому, любой объект, показывающий фильм, должен реализовывать интерфейс IПоказывательФильмов. Человека не интересует, например, как работает прибор, или каким образом он питается (от розетки, аккумуляторов). Телевизор реализует интерфейсы из обоих примеров, портативный DVD-плеер — только второй.
Кто-то не согласится со мной, ткнёт меня в "непреложную истину" про то, что ООП = инкапсуляция + наследование + полиморфизм, а всякие Self и JS — это приходящее. Но, во-первых, не помешало бы для полноты картины не помешало бы знать оба подхода, а во-вторых, ИМХО, подход прототипо-ориентированных языков более интуитивен. Кроме того, как мне кажется, каноническое определение ООП больше относится к технической стороне ООЯ, а вот мыслить человеку в подобных категориях не всегда целесообразно.
... << RSDN@Home 1.2.0 alpha rev. 710>>