vitus_wagner: My photo 2005 (Default)
[personal profile] vitus_wagner
[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 (или другой встроенный базовый тип). Вы уж или штаны наденьте, или крестик снимите. Или у вас объектный язык, тогда от любого используемого типа данных можно породить наследника, переопределив часть его свойств, либо не заикайтесь об ООП.
Page 1 of 3 << [1] [2] [3] >>

Date: 2009-09-23 09:29 am (UTC)
From: [identity profile] karanagai.livejournal.com
Плохой объектно-ориентированный подход, это когда объект НЕОБХОДИМО наследовать чтобы получить уникальный экземпляр.

Золотые слова!


Плохим объектно-ориентированным языком является такой, где нельзя унаследовать int (или другой встроенный базовый тип). Вы уж или штаны наденьте, или крестик снимите.

Ну это уже аргумент не практический, а сугубо методологический. Сугубо методологические аргументы в решении практических вопросов опасны. Ой, у меня тоже методологический аргумент вышел. Даже метаметодологический ;)

Date: 2009-09-23 09:31 am (UTC)
From: [personal profile] ramendik
Насколько я понимаю, в GUI основное преимущество ОО синтаксиса - не наследование, а инкапсуляция. Наследование действительно нужно далеко не в каждой ситуации, а только для нестандартных controls, которых лучше бы иметь минимум.

Date: 2009-09-23 09:34 am (UTC)
From: [identity profile] alexott.livejournal.com
про CLOS еще упомяни :-)

Date: 2009-09-23 09:35 am (UTC)
From: [identity profile] kouzdra.livejournal.com
На мой вкус гуй - как раз чуть не единственное приолжение, где ООП уместна - ООП был придуман для динамического моделирования систем - и там и уместе (а гуй - как раз и есть модель воображаемой real-world-системы).

Использовать же ООП в качестве механизма абстракции данных etc сродни вырезания гланд автогеном и через задницу - то есть если нормальных механизмов нет - и ООП сойдет. Именно поэтому, кстати, наследование из чего угодно ни на фиг не нужно: ничего кроме оверхеда оно не даст.

Другой заменитель - вместо замыканий: тоже стрельба из пушки по воробьям.

Date: 2009-09-23 09:36 am (UTC)
From: [identity profile] karanagai.livejournal.com
никогда бы не подумал что человек с такой строгой позицией относительно ОО программирования будет его использовать в такой специальной области как криптография.

но тем не менее беру свои слова назад в таком случае, ок.

Date: 2009-09-23 09:38 am (UTC)
From: [identity profile] kouzdra.livejournal.com
А не удобнее когда и тот и другой реализуют один и тот же интерфейс (в смысле type classes из Haskell)? Оно как-то эффективнее получается.

Не говоря уж о том, что другой предрассудок - что декларативное наследование - единственный возможный ОО-механизм. Например есть альтернатива (в O'Caml), где отношение subtyping'a определяется не наследованием, а соотвествием типов - если A реализвует все что должно быть в B - значит A подтип B.

А наследование - просто удобный механизм для создания подтипов (но никто не ме мешает обойтись без него просто реализовав тот же интерфес руками)

Date: 2009-09-23 09:42 am (UTC)
From: [identity profile] kouzdra.livejournal.com
Так в гуе все вполне нормально собъектной моделью выходит. Просто не надо на С++ гуй писать - С++ в качестве объеткного языка что-то с чем-то.

Date: 2009-09-23 09:49 am (UTC)
From: [identity profile] kouzdra.livejournal.com
Только вот приводить их друг к другу постоянно приходится.
В смысле?


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


Так это вот как раз одно из вредных последствий ООП - что мышление загоняется в эти рамки. В том же Haskell (который не объектный), некий аналог "методов" связан не с экземпляром, а с типом:

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


Date: 2009-09-23 09:52 am (UTC)
From: [identity profile] kouzdra.livejournal.com
Ну и в lablgtk2 тоже не надо (хотя бывает временами удобно) - а ведь просто binding'и к вполне обычному gtk. Именно потому, что в языке есть замыкания и проч. - то что в С++ действительно оказывается проще всего эмулировать с помощью наследования.

То есть дело не в "нормальной ОО модели", а напротив в том, что в некоторых языках нет других вариантов< кроме как эмулировать какие-то простые вещи с помощью наследования - самый яркий пример - жабский класс Runnable и ему подобные - который по факту просто замыкание эмулирует.

Date: 2009-09-23 09:53 am (UTC)
From: [personal profile] ramendik
Отход от архитектуры фон Неймана уже и в процессоры дошёл. Потому как - безопасность.

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

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

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

Date: 2009-09-23 11:10 am (UTC)
From: [identity profile] begemotv2718.livejournal.com
+1

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

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

Date: 2009-09-23 11:20 am (UTC)
From: [identity profile] taris_marh.livejournal.com
Попытался представить себе наследование для электродеталей... не получилось. Но кошмар должен получиться качественный.

Date: 2009-09-23 11:21 am (UTC)
andrzejn: (Default)
From: [personal profile] andrzejn
Объектно-ориентированное программирование это когда используется наследование с переопределением методов, а не когда у тебя есть предоставленные языком или библиотекой сложные типы данных с операциями над ними.
...
Хороший объектно-ориентированный подход это когда в большинстве случаев ты можешь рассматривать объекты как данность, как такие встроенные типы. А наследовать их - только когда задача ДЕЙСТВИТЕЛЬНО нетривиально.

Хорошее сочетание утверждений :)

О SocketServer

Date: 2009-09-23 11:48 am (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
Объект RequestHandler обрабатывает один единственный запрос. Поскольку запросы могут обрабатываться парралельно в многонитевом сервере, то и объектов может быть несколько. Каждый создаётся, обрабатывается и уничтожается.

В принципе, для обработки эти объекты не нужны, достаточно было бы указывать просто функцию-обработчик, и (сюрприз!) действительно вместо конструктора класса-наследника RequestHandler можно указать просто функцию, принимающую аргументами request, client_address и server. Правда придётся самому следить, чтобы никакое исключение не вылетело за её пределы и аккуратно подчищать хвосты.

Польза от RequestHandler становится видна, когда используются производные классы — StreamRequestHandler и DatagramRequestHandler, в которых инкапсулируется кое-какая вспомогательная работа. Иначе пришлось бы больше писать в пользовательском коде.

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

Date: 2009-09-23 12:15 pm (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
А ООП там и нет. К сожалению. В результате простые вещи делаются легко, а сложные — очень трудно или вообще никак.
Page 1 of 3 << [1] [2] [3] >>

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

August 2025

S M T W T F S
     1 2
3456789
10111213141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 3rd, 2025 08:20 pm
Powered by Dreamwidth Studios