vitus_wagner: My photo 2005 (Default)
vitus_wagner ([personal profile] vitus_wagner) wrote2009-09-23 12:54 pm

Про объекты

[livejournal.com profile] beldmit тут мне задал несколько вопросов про объектно-ориентированное программирование. Которое я систематически ругаю, за то что его использут не по делу.

Ответы я выношу в отдельный пост, поскольку внутри 200-комментной дискуссии их вряд ли кто-нибудь кроме него прочитает.

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

Объектный подход, очевидно, имеет свою нишу. В которой он таки да, естественнен и удобен. Но вот GUI этой нишей не является.

Далее, существует несколько видов объектного подхода. Даже в компилируемых языках на базе C есть Objective-C и C++ с существенно разными объектными подходами. А если мы рассмотрим, скажем, SmallTalk, Python и Ruby, разница будет еще больше. Или можно сравнить несколько объектных систем Tcl, входящих в tcllib. Они существенно разные.

Разбирать, чем именно разные, и в каких конкретно случаях удобна та или иная разновидность, мне сейчас лень.

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

чем тебе не объектное API fopen/fread/fclose?

Тем что FILE * нельзя унаследовать. Вернее, может быть оно и объектное API, но использование объектного API и объектно-ориентированное программирование - разные вещи.

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

Плохой объектно-ориентированный подход, это когда объект НЕОБХОДИМО наследовать чтобы получить уникальный экземпляр. Например, интерфейсы Turbo Vision были устроены так, что для каждого приложения было необходимо порождать наследника от TApplication, а для каждого диалогового окошка - наследника от TDialog.

Еще один пример плохого OO-дизайна - объект SocketServer в стандартной библиотеке Python.

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

Хороший объектно-ориентированный подход это когда в большинстве случаев ты можешь рассматривать объекты как данность, как такие встроенные типы. А наследовать их - только когда задача ДЕЙСТВИТЕЛЬНО нетривиально.

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

Примером хорошего объектно-ориентированного подхода являются перловые модули CGI и DBI.

Плохим объектно-ориентированным языком является такой, где нельзя унаследовать int (или другой встроенный базовый тип). Вы уж или штаны наденьте, или крестик снимите. Или у вас объектный язык, тогда от любого используемого типа данных можно породить наследника, переопределив часть его свойств, либо не заикайтесь об ООП.
ext_605364: geg MOPO4 (Default)

[identity profile] gegmopo4.livejournal.com 2009-09-23 11:00 am (UTC)(link)
Вот очень плохо, что FILE * нельзя унаследовать. Тогда бы и gzopen можно было бы реализовать (или что поэкзотичнее), и sprintf/sscanf были бы не нужны при наличии sopen. Да и в catdoc-е ввод/вывод попрямее был бы.

Tk кстати объектный. Объектный подход оказывается очень уместным для таких сложных систем, как GUI.

[identity profile] taris_marh.livejournal.com 2009-09-23 11:19 am (UTC)(link)
Как я понял, претензия не в том, что объектный он или нет, а в том, что для использования Tk нет необходимости использовать ООП в программе, а можно просто рассматривать классы библиотеки как набор типов. В случае с MFC, wxWidgets и Qt так не получится.
ext_605364: geg MOPO4 (Default)

[identity profile] gegmopo4.livejournal.com 2009-09-23 12:15 pm (UTC)(link)
А ООП там и нет. К сожалению. В результате простые вещи делаются легко, а сложные — очень трудно или вообще никак.

[identity profile] taris_marh.livejournal.com 2009-09-23 12:23 pm (UTC)(link)
Тогда, наверное, надо что-то среднее, чтобы можно было использовать тулкит как данность, но если пржмёт и потребуется хитровывернутое поведение, задействовать наследование и все остальные прелести. Вот сейчас потихоньку разгребаюсь с FLTK - очень похоже на такой идеал: простые вещи собираются из кубиков, но можно и навернуть, если надо - всё-таки на C++ писано. Пока не сильно углубился, но уже нравится. Да и тяжёлые монстры "всё в одном" надоели.

[identity profile] kostix.myopenid.com (from livejournal.com) 2009-09-25 04:48 pm (UTC)(link)
Для "ОО в GUI" ам есть вполне дееспособный Snit, (http://tcllib.sourceforge.net/doc/snitfaq.html) который позволяет привязывать данные к окнам, как и любой популярный гуебилдер типа MFC или Delphi. Расширений, реализующих "ОО без GUI" есть несколько штук на выбор; кроме того, начиная с версии 8.6 ОО будет у тикля в ядре. Правда, ядерного фреймворка для создания мегавиджетов, к сожалению, всё ещё нет.

[identity profile] kostix.myopenid.com (from livejournal.com) 2009-09-25 10:42 pm (UTC)(link)
Мммм. Не могу понять: это многозначительная пустота или пустая многозначительность?
ext_605364: geg MOPO4 (Default)

[identity profile] gegmopo4.livejournal.com 2009-09-26 07:48 pm (UTC)(link)
Пока 8.6 или 9.0 доберутся до тех мест, где имеет смысл использовать Tk, таких мест уже и не останется.

[identity profile] kostix.myopenid.com (from livejournal.com) 2009-09-26 09:53 pm (UTC)(link)
Лично я использую Tk в нужных местах начиная с 8.3, и 8.6 жду без особой экзальтации, хоть и с интересом.

А предсказания скорой смерти Tcl/Tk происходят с регулярностью восходов солнца уже лет десять.

[identity profile] potan.livejournal.com 2009-09-23 03:21 pm (UTC)(link)
В некоторых реализациях можно. Там есть поле, содержащее ссылки на функции read, write и тп.
ext_605364: geg MOPO4 (Default)

[identity profile] gegmopo4.livejournal.com 2009-09-23 03:53 pm (UTC)(link)
«В некоторых реализациях можно» иногда означает «нельзя».

[identity profile] zabivator.livejournal.com 2009-09-23 03:54 pm (UTC)(link)
Эмуляция наследования

[identity profile] potan.livejournal.com 2009-09-24 12:26 pm (UTC)(link)
Нормальное наследование. Это в плюсах - синтаксический сахар ;-).
netch: (Default)

[personal profile] netch 2009-09-23 03:33 pm (UTC)(link)
Для gzopen работают funopen() и fopencookie(). Фактически это _почти_ наследование FILE*.;)) Только свои методы добавлять нельзя.
Ну и не везде это есть (увы)
ext_605364: geg MOPO4 (Default)

[identity profile] gegmopo4.livejournal.com 2009-09-23 03:55 pm (UTC)(link)
Где ж они были тридцать лет назад?