Xpoint
   [напомнить пароль]

Расскажите, пожалуйста, об интерфейсах (не пользовательских)

Метки: [без меток]
2005-10-17 09:35:10 [обр] Григорий Ситнин(0/3)[досье]

Здравствуйте.

Всё чаще слышу о том, что интерфейсы это будущее программирования. Что ввод интерфейсов в пятый пхп — лучшее, что Зэнд мог сделать. Однако, увы, нигде не могу найти описания, которое бы ответило на вопрос "какая польза от этого". К сожалению, везде пишут, что это хорошо и тут же показывают, как это сделать.

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

спустя 1 час 24 минуты [обр] Thirteensmay(0/157)[досье]
Интерфейсы в PHP - расширение ОО-модели с целью предоставления возможности множественного наследования (в некотором роде). На будущее программирования - не тянет. Польза такаяже как и от всего множественного наследования ;( - на эту тему много копий поломано - ищите в сети. В общем данный подход имеет смысл использовать при построении сложной распределенной визуальной среды - с целью стыковки компонентов. Нахрена оно в PHP ? - чтобы тормозило... Может быть это сделано для уподобления Jave, но скорее просто очередная фишка - надо же развиваться смотря вперед ;) А рекламу никто не отменял...
спустя 55 минут [обр] Александр aka Efreeti(0/111)[досье]

Thirteensmay[досье] Если не знаете - лучше молчите. Интерфейсы к множественному наследованию никакого отношения не имеют. Некоторые извращенцы пытаются что-то подобное на них проэмулировать, но это их личные трудности. Опять же, если вы привыкли писать в стиле структурного программирование - пишите дальше, но таким путём вы никогда не вырастите из писателя скриптов о "20 строчках".

Григорий Ситнин[досье], давно я тебя здесь не видел. И мне странно слышать от тебя такой вопрос. Но я попробую ответить.
Интерфейсы нужны для предоставления интерфейсов:). То есть для инкапсулирования того, с каким конкретно классом мы работаем. Если есть несколько классов, и они делают нечто разными способами, но рез-т (конечный) - один, то стоит выдать им интерфейс, дабы не думать потом с кем мы работаем и какой метод вызывать. В php (да и не только) интерфейс в отличие от абстрактного класса-предка "заставляет" имплементировать все методы, которые там объявлены. Тем самым ты можешь быть уверен, что необходимые методы есть во всех классах связанных с этим интерфейсом и можно смело вызывать, не теряя время на method_exists или ещё какие проверки.

Я бы вообще посоветовал почитать книжки про паттерны (шаблоны) проектирования. Вот эту и эту.

спустя 23 минуты [обр] Григорий Ситнин(0/3)[досье]

Александр aka Efreeti[досье] Саша, всё, что ты сказал, я уже слышал. Мог бы ты уточнить, где практическая польза и в чём практическое отличие от абстрактных классов? Почему я не могу просто объявить двух наследников одного абстрактного класса и создавая их из фабрики точно так же ни о чём не задумываться?

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

спустя 12 минут [обр] Александр aka Efreeti(0/111)[досье]

Григорий Ситнин[досье]
Я ж написал:

В php (да и не только) интерфейс в отличие от абстрактного класса-предка "заставляет" имплементировать все методы, которые там объявлены.

И иерархия объектов отдельно, а интерфейсы отдельно. Ну и ты можешь прописать несколько интерфейсов для одного класса, а предок только один.

По поводу шаблонов - они заставляют думать в нужном направлении. Ну и основная идея многих шаблонов - скрытие реализации, в том числе скрытие знаний о конкретном классе (как Abstract Factory) и предоставление единых интерфейсов (Decorator и Adapter).

спустя 2 часа 1 минуту [обр] Давид Мзареулян(14/1003)[досье]

Григорий Ситнин[досье] Вам при работе с объектом совершенно неинтересно, какого он класса. Это дело объекта — какой там Авраам какого Иакова родил, и кто из них в результате породил этот объект. Вам интересно только то, что данный объект умеет. Вот это как раз и есть интерфейс. Предположим, Вы обращаетесь к какой-то функции (сервису), и он Вам выдаёт ссылку на объект и говорит, что этот объект поддерживает интерфейс “Printer”. Вам после этого совершенно всё равно, что это за объект: LPT1Printer->HewlettPackardPrinter->LaseJetIVMV или TCPService->NetworkPrinter->BigPrintServer. Для Вас главное, что Вы можете вызвать метод print() этого объекта. В данном случае при желании не составит труда наладить печать в PDF-файл или, скажем, “в e-mail”. Даже если изначально почтовый класс не поддерживал этот функционал и наследовался совсем от других корней. Достаточно будет просто в определённом месте реализовать метод print() и декларировать реализацию интерфейса “Printer”.

А рожать все объекты одинакового функционала от единого базового класса очень часто неудобно, а в случае распределённых систем и вовсе невозможно.

спустя 35 минут [обр] Thirteensmay(0/157)[досье]
Александр aka Efreeti[досье] IMHO как раз надо вырасти в писателя скриптов о "20 строчках" - на основе того что есть сразу делать законченные решения, а не раздувать их до безобразия - PHP не тот инструмент. Если учитывать что никто не запрещает определять все методы в классах предках, то отличие интерфейса заключается лишь в том что их у обьекта может быть несколько, что можно использовать как множественное наследование. Далеко не я один не использую шаблонов - в большинстве случаев все можно сделать гораздо проще и эффективнее, а вот засунуть общий функционал в интерфейс - с удовольствием. Я не против ООП и давно его использую там где это имеет смысл. Замечательно что есть люди с такими подходами как у Вас - это приносит свои медленные но гибкие и самое главное - прогрессивные плоды, а есть такие как я - надо чтобы работало "вчера". Пишите, если закончите - может быть будем юзать...
спустя 36 минут [обр] Александр aka Efreeti(0/111)[досье]

Thirteensmay[досье]Знайте, есть такой подход: "Заставь это работать, потом заставь это работать хорошо". "Хорошо" в том числе относиться и к коду/архитектуре. И вроде бы всё замечательно, но очень часто, особенно когда нужно "вчера" и "интерфейсы - тормозная туфта", про второй пункт как-то забывают. Ведь платят не за красивую архитектуру, а за работающий продукт. Ну и ладно, чего париться-то. И только потом, когда приложение разрастется, вам придется прилагать кучу усилий, чтобы внести небольшое изменение, вы поймете, что были не правы.

Я не просто так это говорю - я в своё время наступил на эти грабли (правда не в php а в js, но это не сильно меняет), так что могу судить что к чему.

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

спустя 39 минут [обр] Григорий Ситнин(0/3)[досье]
Александр aka Efreeti[досье], Давид Мзареулян[досье]: Всё, что вы говорите, я уже знаю. Дело в том, что до сих пор мне совсем не ясно, как это можно с пользой применить на практике (где, когда, почему). Могли бы вы привести конкретные примеры, когда реализация через интерфейсы является "тем самым"?
спустя 9 минут [обр] Давид Мзареулян(14/1003)[досье]
Григорий Ситнин[досье] Тогда просто подождите, пока перед Вами встанет подходящая задача. То, что это «то самое», Вы сами почувствуете:)
спустя 1 минуту [обр] Григорий Ситнин(0/3)[досье]
Давид Мзареулян[досье], видите ли, я практически уверен, что она есть. Да и как-то хочется, чтобы знания уже были на момент появления задачи (если ещё нет =).
спустя 1 час 55 минут [обр] Александр aka Efreeti(0/111)[досье]
Григорий Ситнин[досье] Ну самый, наверное, банальный пример - получение данных.
Т.е. есть много разных классов загрузки информации (какого-то определённого типа): кто-то берёт из БД (и таких может быть несколько, для каждого типа СУБД), кто-то из памяти, кто-то из файлов и т.д. Реализация у всех разная (естественно), но интерфейс один - getData(). Выяснением кого мы в данный момент создаем, занимается фабрика. Нам же только остается получить из неё объект, вызвать известный метод и получить результат. Если на нужно уточнить, какую конкретно информацию мы хотим получить (на пример по id), то мы добавляем в интерфейс метод setId($id), который мы вызываем перед getData(). И на первом же тесте мы сразу получим ошибку, что некоторые классы не имплементируют метод setId(), и нам останется его только реализовать там.
спустя 3 часа 49 минут [обр] Григорий Ситнин(0/3)[досье]
Хм, Саш, а вот ты подумай сам: ну, если я объявлю в AbstractDataReader методы abstract getData() и abstract setId(), который обязаны быть перекрытыми в потомках, то в чём будет отличие? Вероятно, это не тот пример, который показывает полезность интерфейсов, а только иллюстрация вышесказаных идей (о которых мы договорились, что они понятны).
спустя 38 минут [обр] Thirteensmay(0/157)[досье]
Александр aka Efreeti[досье] т.е. Вы хотите сказать что весь сыр-бор из за улучшения структурированности ? Я думал что это несколько больший шаг - с прицелом на будущее. Вот другой пример: Имеем классы Photo, RegInfo, Contacts и пр. на основе которых лепим класс User - разве не удобно ? Хаки конечно, но все же куда более полезно. Впрочем просветлили - Спасибо, извиняюсь...
спустя 37 минут [обр] Григорий Ситнин(0/3)[досье]
Thirteensmay[досье] Что-то ваш пример я совсем не понимаю. Вы о чём? О замене множественного наследования?
спустя 1 минуту [обр] Григорий Ситнин(0/3)[досье]
Кстати, улучшение структурированости само по себе также даёт очень много, IMHO.
спустя 28 минут [обр] Thirteensmay(0/157)[досье]
таки Да - на оба Ваших поста ;)
спустя 13 минут [обр] Александр aka Efreeti(0/111)[досье]

Грегор[досье], ты мне объясни, как ты заставишь их перекрываться в потомках? Напишешь die в абстрактном методе? Так это в четверке так извращались, когда не было интерфейсов. Плюс ты обязан наследоваться от этого AbstractDataReader, хотя может лучше было бы по-другому построить иерархию. Ну и, наконец, у тебя может быть класс, который имплементирует несколько интерфейсов. А другой класс может реализовывать только часть из них. Та самая гибкость.

Thirteensmay[досье]Хаки - они только на крайний случай. Лучше без них обходиться. Это всё равно что в рабочем коде основываться на debug_backtrace - можно конечно, но это дикий изврат.
О прелестях и недостатках множественного наследования очень много было разговоров, много копий сломано, и обсуждать это ещё не стоит, тем более что это оффтопик. Рад, что вы меня поняли :)

спустя 12 часов [обр] Давид Мзареулян(14/1003)[досье]
Интерфейсы позволяют отделить полиморфизм (который важен только с точки зрения использования объекта) от наследования (которое важно только с точки зрения конструирования объета). Всё. Никакого больше сокровенного знания в интерфейсах нет, и ничего больше про них сказать нельзя. Когда связка полиморфизм—наследование начнёт быть для Вас слишком ограничивающей — переходите на интерфейсы. А до той поры не заморачивайтесь.
спустя 1 час 28 минут [обр] Григорий Ситнин(0/3)[досье]
Давид Мзареулян[досье]: Вот, это практически то, что я хотел услышать. Спасибо. Реально. Но вот теперь ещё один вопрос: а когда такая связка в реальной жизни станет слишком ограничивающей (хотелось бы пример, чтобы понять)? Как я уже говорил, хочется такую ситуацию детектировать на ранней стадии.
спустя 4 минуты [обр] Григорий Ситнин(0/3)[досье]

Александр aka Efreeti[досье], если я ничего не путаю, но абстрактные методы обязаны быть перекрытыми в конкретных потомках. Или нет? Но после тебя и Давид Мзареулян[досье], кажися, начинаю понимать, где тут счастье зарыто.

Кстати, о хаках — они вообще зло. Из-за перезаписи $self в php4, как делали многие хорошие программы (PhpDocumentor, например) с php5 они не работают в принципе, даже в режиме совместимости. Но это так, к слову =).

спустя 1 час 34 минуты [обр] Александр aka Efreeti(0/111)[досье]
Григорий Ситнин[досье] Про обязательства здесь ничего не написано.
спустя 3 минуты [обр] Григорий Ситнин(0/3)[досье]
Александр aka Efreeti[досье]: Ну, косвенно там в примере есть, однако, интерфейсы меня вообще интересуют, а не только в пхп. Но я вполне допускаю мысль, что абстрактный метод может, но не должен быть перекрыт в потомках. Кстати, кто-нибудь в курсе, что на это говорит теория ООП?
спустя 1 час [обр] Александр aka Efreeti(0/111)[досье]
Григорий Ситнин[досье] А нет никакой теории ООП, точнее нет стандартов, которым бы хорошо следовать. В каждом языке свои особенности. Например в С++ вообще нет выделенных интерфейсов, там можно только объявить абстрактный класс и от него наследоваться. Но т.к. там есть множественное наследование, то есть возможность реализовывать несколько интерфейсов, но они не заставляют переопределять абстрактные методы.
Как оно работает в Java и C# - я не знаю, пусть выскажутся знатоки этих языков.
спустя 2 часа 58 минут [обр] Григорий Ситнин(0/3)[досье]
А нет никакой теории ООП
Да ладно. Что стандарта нет — это понятно, но Computer Science ещё никто не отменял, а она, в частности и ООП изучает, если я не ошибаюсь. =) Но что-то мы от темы удаляемся.
спустя 4 года 1 месяц [обр] Andrew[досье]
по теории все понятно, а кто может помочь с примером? напр. есть два класса "Класс1БД" и "Класс2ФС" которые реализуют методы "Читать" и "Писать" интерфейса "Интерфейс". и есть 3-й класс, который использует нужный метод интерфейса в зависимости куда писать. как правильно организовать код PHP в соответствии со всеми канонами программирования?
спустя 22 часа [обр] balou(0/23)[досье]
Если не знаете - лучше молчите. Интерфейсы к множественному наследованию никакого отношения не имеют. Некоторые извращенцы пытаются что-то подобное на них проэмулировать, но это их личные трудности.

Александр aka Efreeti[досье], фу, какая грубая глупость, а вот и еще пачка

А нет никакой теории ООП, точнее нет стандартов, которым бы хорошо следовать. В каждом языке свои особенности. Например в С++ вообще нет выделенных интерфейсов, там можно только объявить абстрактный класс и от него наследоваться. Но т.к. там есть множественное наследование, то есть возможность реализовывать несколько интерфейсов, но они не заставляют переопределять абстрактные методы.

сразу видно, что "академиев не кончал". Советую почитать Страуструпа прежде, чем упоминать C++ в разговоре о пхп. Ведь разговор о пхп, правильно я понял? А если нет, и обсуждается действительно ООП, то предлагаю абстрагироваться от пхп и почитать хотя бы Википедию, раз уж на большее сил не хватает.

спустя 3 минуты [обр] balou(0/23)[досье]
не обратил внимание на дату, спорю с призраками, виноват :-)
спустя 1 час 11 минут [обр] Илья Cтpeльцын aka SelenIT(0/171)[досье]
Andrew[досье], в зависимости от того, куда писать, этот третий класс должен выбирать, с каким конкретным классом чтения/записи работать. А методы как раз, вне зависимости от выбранного класса, вызываются одни и те же. В этом-то, насколько я в курсе, главная прелесть общего интерфейса и состоит — это и есть полиморфизм.
спустя 1 год 4 месяца [обр] true_false[досье]
к слову, если я правильно понимаю но не факт, потому как сам пытаюсь глубоко понять ООП. интерфейсы, также гарантируют наличие методов в объекте к которому имплементирован интерфейс, следовательно используя этот объект в других объектах, используя instanceof или при передаче его в конструктор __construct( Core $o ); мы будем знать точно на 100% что мы можем использовать набор методов описанных в интерфейсе.
спустя 15 минут [обр] Григорий Ситнин(0/3)[досье]
true_false[досье], вы, боюсь, путаете причину и следствие )
спустя 18 дней [обр] Ilya Erlikhman[досье]

Тут вы, по-моему, вообще все перепутали. При взаимном использовании классов приложения становятся зависимы друг от друга. Интерфейсы позволяют унифицировать обращения, и при этом избежать появления зависимостей при интеграции.

Что же касается web-приложений, тут для интеграции больше подойдет протокол http. Или SOAP.

Powered by POEM™ Engine Copyright © 2002-2005