• Авторизация


Абстракции, ООП и прочее 07-12-2010 13:00 к комментариям - к полной версии - понравилось!


Я так вдохновился холиваром у своего друга, что решил полностью расписать здесь все что я думаю по этому поводу
Быстро выстроить хорошие абстракции очень сложно. Нет, конечно, если человек может делать это быстро, то у него превосходный интеллект, я бы сказал на уровне гениальности, но много ли таких людей? Обычные люди, как убедительно показывают исследования в области истории науки, абстракции, не формулируют перед началом работы, а находят в процессе исследований. Абстракция - это обобщение свойств. А как можно начать обобщение свойств, когда компоненты ещё не написаны? Конечно, можно указать множество ситуаций, в которых можно прибегнуть к имеющемуся опыту. Например, кнопка там, или итератор, они и в Африке кнопка или итератор. Но что если программа к этому не сводится? Когда абстракции понятны - ООП рулит, очевидно и неоспоримо. Расширяться тоже можно просто и без проблем, реализуя уже найденные интерфейсы.
Но для новых проектов всё это ООП - зло. Оно заставляет поиск решения производить задом наперёд: придумали абстракцию начали делать, а потом, хопа, поняли, что всё это работать не будет, и начинается изменение всей иерархии. Это же сложно и время отнимает, поэтому люди начинают нарушать парадигму на право и налево. Но возникает вопрос: а зачем тогда вообще они начали писать свои классы?
Насчёт free. Частое использование malloc/free - это результат неправильного проектирования, по моему мнению. И является болезнью больших проектов, в которых писают всё написать на C. Но C придумывался не для этого. Компоненты, написанные на C должны быть маленькими и максимально специализированными под решаемую задачу. Большая же решается через объединение компонентов через IPC. Это удобнее, чем придумывание иерархий, потому что позволяет вклиниваться и менять взаимодействие между компонентами как угодно.
Попробуйте воткнуть дополнительную обработку в pipe, или дополнительную обработку во взаимодействие между двумя объектами, когда один вызывает другой. Как минимум, придётся нечто наследовать, заново думать над тем, что должно быть виртуальным или не виртуальным. И так далее. Много работы. Может быть, именно поэтому, все сложные ОО системы рано или поздно приходят к тому, чтобы создать свою транспортную систему данных между объектами. Или воспользоваться существующей в виде базы данных или чего-нибудь, вроде, CORBA. Но это всё усложнения, усложнения и ещё раз усложнения. Которые надо осваивать, особенно при коммерческом программировании, а это всё уводит сознание от размышлений над другими методами организации вычислений. Существенно более гибкими и простыми. Ну вот сравнить хотя бы ту же CORBA с plumber'ом из Plan9 или Linda.
Поэтому я против ООП. Мне не нравится, когда навязываются сложности и неэффективности, да ещё такими ненаучными способами: вы хотя бы в одной книге по ООП видели сравнение предлагаемых способов решения тех или иных иных задач в этой парадигме с решением их в других?
вверх^ к полной версии понравилось! в evernote
Комментарии (7):
Долас 07-12-2010-13:08 удалить
Так, сейчас я все расскажу...
Теоретически, всё верно. Но быстро выстроить хорошие абстракции очень сложно.



Это касается так же и C. И разницы под что их собственно строить особой нет.


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



Процесс исследования и проектирования может быть различным.


Абстракция - это обобщение свойств. А как можно начать обобщение свойств, когда компоненты ещё не написаны?



А зачем вам для поиска компонент писать код? Для поиска компонент и последующего выведения абстракций существует к примеру ручка и бумага или UML, который позоволяет автоматически генерировать классы и объекты.


Когда абстракции понятны - ООП рулит, очевидно и неоспоримо.



А когда они не понятны, то как вас спасет функциональный или процедурный подход?


Но для новых проектов всё это ООП - зло. Оно заставляет поиск решения производить задом наперёд: придумали абстракцию начали делать, а потом, хопа, поняли, что всё это работать не будет, и начинается изменение всей иерархии. Это же сложно и время отнимает, поэтому люди начинают нарушать парадигму на право и налево. Но возникает вопрос: а зачем тогда вообще они начали писать свои классы?



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



Это же сложно и время отнимает, поэтому люди начинают нарушать парадигму на право и налево. Но возникает вопрос: а зачем тогда вообще они начали писать свои классы?



А что частный случай неудачного применения ООП уже указывает на неудачу парадигмы в целом ? Интересно интересно :)


Насчёт free. Частое использование malloc/free - это рузультат неправильного проектирования, по моему мнению.



И как вы будете реализовывать FIFO без частого использования malloc/free ?


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



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


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



Для решения такой задачи существует специальный паттерн. И унификация интерфейсов. Опять же с pipe сравнивать не корректно. Так как pipe представляет из себя поток байтов. Я тоже могу реализовать такой интерфейс в ООП и он будет точно так же работать как и в не ООП.


Мне не нравится, когда навязываются сложности и неэффективности, да ещё такими ненаучными способами: вы хотя бы в одной книге по ООП видели сравнение предлагаемых способов решения тех или иных иных задач в этой парадигме с решением их в других?



А вы хоть в одной книге по функциональному программированию или по процедурному видели такое сравнение? Думаю что нет. Собственно эти книги знакомят вас с технологиями, а не с тем чем лучше или хуже та или иная технология. Если же говорить про ООП, то в прикладных областях использование этой парадигмы вполне оправданно, так как она позволяет получить результат существенно быстрее, чем процедурная или функциональная парадигма.
Aendor 07-12-2010-13:15 удалить
Функциональное программирование больно той же самой болезнью: нужно проектировать задом наперёд. Сначала проектируется общий вид основной функции, а потом всё ниже и ниже проектируются вспомогательные. То же самое в ООП: сначала проектируем интерфейс, а потом пытаемся реализовать. И если интерфейс оказался неподходящим, то переделывать придётся весь код. Если высокоуровневая функция в функциональном подоходе оказалась неподходящей, то переделывать весь код придётся в гораздо большей степени, чем в императивном ООП.

Оба подхода заставляют по форме (что должно быть) определить содержание (как должно быть). Вобщем-то вполне себе математичный подход. Теоретически красивый. Да, мы вот сейчас всё пишем и пишем, и на словах, действительно ООП гораздо красивее обычного структурного подхода. Кроме того, можно кучу книжек писать, ООП - богатая среда для мудрствований, например, вот те же замечательные философствования о шаблонах и рефакторинге. Так же как и функциональное программирование, а когда оно ещё и с монадами, то вообще, ууУУух как поумничать можно и статьи пописать.

C же освобождает от необходимости проектировать строго определённый интерфейс, конечно, от ответа на вопрос: что код должен делать? уйти вряд ли удасться, но ответ этот может быть достаточно нестрогим. Язык ориентирован на работу с данными, а не объектами. Если я совершу ошибку на этапе придумывания интерфейса, то мне никто не мешает напрямую залезть в структуру данных, и написать новый код для работы с ней, в том месте, где он нужен. Да, это грязно, это не математично, это нарушение кучи принципов, об этом не напишешь умную книжку, потому что это глупо, но это работет. И работает не только корректно, но и эффективно. Если подобный код мне нужен будет во многих местах - родилась абстракция - я его вынесу в соответсвующий модуль, и доступ к нему сделаю частью интерфейса.

Мог бы я подобное обнаружить на бумажке? Запросто, если бы писал на бумажке настоящую программу, до уровня операторов и вызов функций, а не просто рисовал бы стрелочки, то наверняка обнаружил бы то же самое. Но на бумажке невозможно написать нечто более или менее сложное.

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

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

Да, всё то же самое можно делать и на C++, например. Но тогда надо будет делать все данные и методы изначально открытыми, и возникает вопрос, а зачем тогда этот весь этот лишний классовый синтаксис?

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

И последнее замечание: в книжках по функциональному программированию, обычно, всё истолковывается в терминах и примерах из императивных языков программирования, поэтому, в них со сравнением с другими технологиями всё лучше.
Долас 07-12-2010-13:26 удалить
Функциональное программирование больно той же самой болезнью: нужно проектировать задом наперёд. Сначала проектируется общий вид основной функции, а потом всё ниже и ниже проектируются вспомогательные. То же самое в ООП: сначала проектируем интерфейс, а потом пытаемся реализовать. И если интерфейс оказался неподходящим, то переделывать придётся весь код.



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


Оба подхода заставляют по форме (что должно быть) определить содержание (как должно быть). Вобщем-то вполне себе математичный подход. Теоретически красивый. Да, мы вот сейчас всё пишем и пишем, и на словах, действительно ООП гораздо красивее обычного структурного подхода. Кроме того, можно кучу книжек писать, ООП - богатая среда для мудрствований, например, вот те же замечательные философствования о шаблонах и рефакторинге. Так же как и функциональное программирование, а когда оно ещё и с монадами, то вообще, ууУУух как поумничать можно и статьи пописать.



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


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



А кто вам сказал, что в C++ или любом другом языке мне требуется проектировать очень строгий интерфейс? Я могу определить где-то так. Дальше уже расширить интерфейс и где-то пару методов.


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



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


Да, это грязно, это не математично, это нарушение кучи принципов, об этом не напишешь умную книжку, потому что это глупо, но это работет.



Глупо и не математично не предерживаться структурирования программы. Если в ООП у вас код структурируется за счет собственно объектного подхода, то в случае процедурного программирования вам надо думать над этим самому. Да это бывает эффективно. Особенно в том случае если сложность проекта не высока. Так как в этом случае начинается перевозка кучки песка карьерным самосвалом.


Мог бы я подобное обнаружить на бумажке? Запросто, если бы писал на бумажке настоящую программу, до уровня операторов и вызов функций, а не просто рисовал бы стрелочки, то наверняка обнаружил бы то же самое. Но на бумажке невозможно написать нечто более или менее сложное.



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


В итоге, конечно, у меня тоже появляются объекты в программе, но границы у них не жёсткие, а размытые, и объекты именно появляются, а не спускаются сверху.



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


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



В большинстве случаев взаимодействие может быть сложнее, а не проще. И использовать ваш объект или расширять его будет сложнее.


Да, всё то же самое можно делать и на C++, например. Но тогда надо будет делать все данные и методы изначально открытыми, и возникает вопрос, а зачем тогда этот весь этот лишний классовый синтаксис?



Можно. Но если вам необходима именно такая структура, то вам стоит посмотреть python, там как раз так. Меня иногда раздражает.


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



Они появились ровно в тот момент когда Страуструп захотел получать хорошо расширяемый и повторно используемый код. Увы для этого требуется проектирование сверху вниз.


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



Обычно только самое начало.
Долас 07-12-2010-13:28 удалить
Человек хочет сам все контролировать :) У меня такого желание уже давно нет :)
Rusov 07-12-2010-13:31 удалить
эволюция нах. Люди в чем мать родила, не моясь, не питаясь по человечески сутками проводят у компьютера. Серфя сайты, изучая неизученное, уведая неизведонное.
Вскоре появится следующий шаг цивилизации, но на людей это будет слабо похоже. Некие , как в дальнейшем их назовет пресса, будут представлять из себя лишь мозг в защитной оболочке. Некоторые (самые модные) будут иметь полупрозрачную защитную оболочку.
Перемещаться они будут силой мысли, питаться спамом в гостевых, блогах и на почту. Спамеры же в конечном итоге разорятся, ибо Иные в состоянии голода будут брутить за доли секунд пассы на любые мыла и питаться спамом из них. В итоге, когда спама не останется, они найдут новый способ извлечения энергии - они научатся перехватывать длинные волны беспроводных сетей. Они будут поступать очень хитро. Вместо того чтобы портить сигнал, они научатся расшифровывать его и питаться только избыточностью от шифрования, отправляя сигнал дальше в обычном виде.
SerfMaster 07-12-2010-13:34 удалить
C/C++ & C#.
PHP4/5.

Из них C# - самый красивый :)
Teg177 07-12-2010-13:40 удалить
В заголовке ошибка....А он на всю необъятную Родину светится...


Комментарии (7): вверх^

Вы сейчас не можете прокомментировать это сообщение.

Дневник Абстракции, ООП и прочее | Aendor - Текст как-то по-дебильному написан (с) | Лента друзей Aendor / Полная версия Добавить в друзья Страницы: раньше»