Я, наверное, знаю ООП. Опыт объектно-ориентированного программирования и дизайна. Ответ «не знающим ООП.»

После появления статей типа "Я не знаю ООП" — возникает желание внести ясность, «сорвать покровы» и «докопаться до истины».

Принципы объектно-ориентированности


Обычно выделяют (читай: на собеседовании требуют назвать) четыре «принципа объектно-ориентированного программирования»: абстракцию, инкапсуляцию, наследование и полиморфизм.

На мой взгляд (не говоря о том, что абстракция и полиморфизм могут быть запросто отнесены к подразделам наследования), принцип тут один, в общем, тот же самый, что при проектировании баз данных: представление всего в виде объекта — некоторой штуковины со свойствами. Набор обычно бывает фиксированным, и тогда говорят о классе объектов, а даже если понятия класса и нет, то наличие свойств с определёнными названиями подразумевается логикой программы, т.е. нечто типа класса в виде некоего минимального набора свойств всё равно присутствует. В общем, воззрения восходят к давнему С-шному/паскалевскому типу данных struct/record. Потом к этому добавили немного «функциональности» (в смысле функционального программирования): значением свойства может быть функция, причём такая, которая имеет доступ к самой структуре/записи, значением одного из свойств которой она является. Сей феномен, в лучших традициях немецкого латиноязычного нейминга (когда опция называется «вариантом», а степень числа — «потенцией»), назвали «методом». Желание повторно использовать код, в сочетании с представлением каждого предмета как некоего подобия паскалевской «записи», привело к появлению концепции «наследования».

С появлением «методов» всплыл ещё один приятный момент в части организации функционала: вместо создания 900 функций с перекрёстно дублирующимися первыми и вторыми половинами названий (помните WordBasic?) можно сделать 30 классов с 30 методами в каждом.

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

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

Критика. Наследование. Рождение интерфейсов


С развитием концепции наследования хочется иметь возможность того, чтоб объект принадлежал сразу к нескольким классам, не являющимися по отношению друг к другу родителем и потомком. Это можно сделать, введя возможность множественного наследования. Но, как выяснилось, настоящее множественное наследование обычно порождает проблему «ромбического наследования»: при наследовании от двух потомков одного класса непонятно как разруливать многократное наследование одних и тех же его членов — полей, свойств и методов.

Проблема в значительной мере разрешилась изобретением «интерфейсов» — полностью абстрактных классов, в которых в качестве членов разрешались только чисто виртуальные, т.е. абстрактные, методы. «Места для вставки статических реализаций» (а в общем-то любой метод класса в строго типизированном языке, если его рассматривать как значение чего-то, является статическим: это «значение» — определение метода — одинаково для всех экземпляров класса) — единственное, что разрешалось в этих методах — не могло, по определению, вызвать проблем при «ромбическом наследовании». Тем более, с распространением инкапсуляции, когда «наружу торчат» только методы, это не воспринимается как нечто экстраординарное.

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

Критика. Почему так мало «настоящих» классов. Multiple dispatching. Рождение «менеджеров» и отделение их от Domain objects. Синглетоны



Считается, что класс — это набор свойств плюс «поведение». Вспоминаю прочитанные в 1998 году слова из хелпа к VisualBasic 5, что-то вроде: «Method is what you tell object to do. Event is what object tells you is done upon it». Так что насчёт «поведения» тут ещё вопрос – метод или ещё что-то.

Проблемы дизайна начинаются, когда «поведение» включает два и более класса. Как тут в комментарии — «Рост, вес, возраст — свойства. Ходить, сп(р)ать — поведение.» Вот с случае моделирования поведения с буквой «р» возникают ещё Чем и Куда (да и «ходить» тоже — есть ещё и Куда). В общем, когда в действии участвуют несколько непримитивных классов, при разоработки объектной модели возникает вопрос — и к какому же из двух, трёх, четырёх и т.д. классов — в данном случае «кто», «чем» или «куда» — должен принадлежать метод, моделирующий это действие? И в любом случае это, скорее всего, будет tight coupling и в процессе дальнейших наращиваний системы (а постоянное дописывание, расширение и улучшение должно рассматриваться как штатная, а не исключительная ситуация) «вылезет боком».

Эта проблем решается выделением специальной сущности — «менеджера». В результате у объекта типа «банковский счёт» не остаётся метода перевести_на(счёт, сумма), а вместо этого у объекта типа «менеджер счетов» появляется метод перевести_с_на(с_счёт, на_счёт, сумма).

У собственно классов, которые не «менеджеры», а отражают объекты реального мира — domain object classes, при продолжении такой тенденции вообще не остаётся методов кроме тех, что требуются для обеспечения принципа инкапсуляции — самых примитивных акцессоров и мутаторов. И что характерно, в той объектной системе, в которой проблема multiple dispatching решена сразу и радикально — в CLOS – методов как таковых нет, а есть специальные одноимённые функции с разными типами аргументов, которые принадлежат всей системе.

Что интересно, в общем случае о типе «менеджер счетов» тут не надо знать ничего кроме того, что у него есть метод перевести_с_на(с_счёт, на_счёт, сумма). Т.е. это — типичный интерфейс с реализацией. И если потребуется поменять механизм обеспечения целостности данных (с транзакций на ручные блокировки или наоборот) — то не потребуется переписывать код типа «счёт», переписывать вообще ничего не потребуется (и перетестировать что-то старое, соответственно, тоже не потребуется), потребуется только написать новую реализацию интерфейса.

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

Возникает вопрос — если в классе нет свойств, существенных с точки зрения объектной модели куска реальности, если он не моделирует ни одного физического объекта, то сколько его экземпляров должно существовать? Не хватит ли вообще одного? В общем, чем экземпляров меньше, тем лучше, и количество определяется техническими причинами — например, по одному на коннекцию из пула. В особо вырожденном случае достаточно одного экземпляра, тем более если его создание довольно ресурсоёмко. Это и называется шаблон проектирования «синглетон» — «одиночка». Класс пишется так, что существует его единственный экземпляр, получаемый через статический метод.

В сегодняшнюю эпоху, когда вопрос инстанциирования сервисных классов отдаётся на откуп разным инжекторам зависимостей, реализация паттерна «синглетон», как пример жёсткого ручного управления инстанциированием, является чем-то вроде разновидности tight coupling и, поэтому, нарушением принципа проектирования и очень не-комильфо.

Критика. «Хочу переопределяемый конструктор». Фабрики


Использование конструкторов со сложным поведением, как и интенсивное использование наследования, является, в общем, примером tight coupling (полей и интерфейса, хе-хе) и, в связи с этим, моветоном. При вызове конструктора класса-потомка вначале вызовутся конструкторы всех классов-предков, что, в общем, нередко не надо и вообще ресурсоёмко и просто вредно. Лучше логику инстанциирования класса сосредоточить в отдельном сервисном классе, загнав в него заодно и всю «предпродажную подготовку». Сервисный класс можно оформить как интерфейс и так далее со всеми уже описанными остановками. Получается «фабрика».

У фабрики есть ещё пара плюсов: 1) может вернуть null и 2) может возвращать один и тот же объект много раз.

Критика. Примитивы и прочие Value objects. Иммутабельность. Интернизация.



Принцип «всё есть объект», конечно, привлекает своей последовательностью. Хотя изначально предполагается, что значения свойств объектов сами не являются объектами. И, вообще, у системы классов должны быть в конце концов выходы в «реал», а «реал» — это всегда данные одного из FoxPro-шных типов: число, строка, дата-время или да/нет. Поэтому, если не требуется чрезмерная гибкость, то лучше не делать всё объектами и оставить некоторые не-объектные типы данных.

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

C примитивами по своему замыслу граничат Value objects. Это объекты без специальных методов, имеющие набор свойств со значениями, примитивными или тоже Value objects, которые проверяются на равенство исходя не из физической одинаковости (одинаковости ссылок на них), а из значений свойств.

Нередко (даже, скорее, как правило) Value objects делают иммутабельными, т.е. неизменяемыми. Иммутабельность позволяет безбоязненно использовать сложные value objects в качестве ключей и вообще даёт кучу дополнительных «плюшек», в частности, иммутабельный квадрат может без какой-либо «задней» логики быль наследником иммутабельного прямоугольника, чего нельзя сказать об их мутабельных версиях.

Рядом с концепцией иммутабельности идёт концепция интернизации — чтобы все равные (в смысле значений свойств) объекты определённого класса были равны и физически, т.е. были одним и тем же объектом. Это обеспечивается хранением всех когда-либо использованных экземпляров данного класса в статическом или по-иному «сиглетонном» множестве (Set), и, в идеале, получением нового только через «фабрику», «пропускающую» всю «продукцию» через проверку на уникальность и выдающую только уникальные экземпляры. На фазе создания это сильно тормозит, но использование потом ускоряется многократно.

Классы IRL. Критика. «Некоторые классы равнее других»


Близко к вершине пирамиды классов «равноправие» и равноценность классов нарушается. Особенно когда хочется «обуть в объектно-ориентированность» саму среду выполнения.

В языке Java корневым классом для всех классов является класс Object. Но у класса Object есть метод getClass(), возвращающий объект типа Class, и метод toString(), возвращающий объект типа String. Также имеет методы, бросающие CloneNotSupportedException, InterruptedException, IllegalArgumentException и Throwable. При этом классы Class, Throwable и String являются прямыми потомками класса Object, а CloneNotSupportedException, InterruptedException и IllegalArgumentException — даже более чем непрямыми. В общем-то, класс, имеющий в половине методов, ссылки на его заведомых потомков, нередко непрямых — это bad design (как и всякие циклические зависимости), но «если нельзя, но очень нужно, то один раз можно». Да и корневой класс для исключений и ошибок — Throwable — тоже содержит в себе ссылки на своих непрямых потомков: IllegalStateException и IllegalArgumentException, так что, опять-таки, в ограниченной дозировке «не догма».

Хотя, классы String и Class — финальные, т.е. не могут иметь потомков, что снижает «криминальность» их использования в классе Object.

Классы IRL. Чем они стали в конце концов


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

Наследование, как и прицепливание алгоритмов к классу domain object’а, признано tight coupling и bad practice, и применяется строго дозированно. В частности, предпочтительным способом реализации сущности «социальный аккаунт» для программы, работающей с разными социальными сетями, является не создание абстрактного класса SocialAccount с потомками FBAccount, VKAccount и TwitterAccount, а создание нормального domain class’а SocialAccount и фабрик-конвертеров в него из данных от разных социальных сетей, может быть даже JSON-to-SocialAccount-конвертеров. Напоминает ORM? Так ещё лет 10 назад всё было обратно: были распространены DB-persistence-платформы, в которых логика чтения/записи БД находилась в методах самих персистируемых классов, из-за чего они должны были наследоваться от специального класса типа какого-нибудь DBExternalizableObject. В последствии, «как известно», от этого отказались.

Современные domain classes, кроме того, на деле почти всегда являются «прослойкой» к записям в таблицах баз дынных и проектируются изначально в СУБД или в средстве проектирования СУБД.

А «нормальные», «классические» классы со свойствами, методами и наследованием встречаются в основном в серверах приложений и прочих библиотеках.

UPD: В комментариях правильно подсказали, что надо было говорить не о «строгой» типизации, а о «статической». Регулярно путаю, и не один.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 144

    +23
    Вот честно, надоели эти названия статей «Я не знаю ООП», «Я знаю ООП».
      +2
      Ну в СМИ сейчас модно пиариться на теме пуси райотс. Вон, даже какой-то хельсинский профессор отметился :) А на хабре для этого есть «Я [не] знаю DDD/Patterns/UnitTests итд». :)))))
        0
        =)) Да, но предел всему есть=) Мне нравится читать про ООП, но название статьи отбило все желание, поскольку статей с таким названием на хабре, увы, зашкаливает.
        +5
        Следующая наверное будет: «Я, наверно, не знаю ООП».
          0
          И к ней ответ: «Угадай, кто знает ООП?» )
            +5
            «Я не знаю ООП и я этим горжусь»
              +2
              OOP has you.
                –1
                О! хватило бы кармы — дал бы плюс.
              0
              «Я, наверное, никогда не буду знать ООП»
              «Я, наверное, знаю о том, что ничего не знаю»
              «Я знаю ООП, но могу ошибаться»
              «Я узнал о том, что не знал ООП»
              «Я знать ничего не знаю, тем более ООП»

                0
                «Я точно знаю: по-настоящему знает ООП только Господь Бог»
                  0
                  Может ли Бог придумать такую ООП-архитектуру, в которой сам не разберётся?
            +2
            Инкапсуляция, в частности, делает возможным проксирование.

            Можно подробней?
              0
              Средствами контейнера наинженерить класс-наследник-обёртку, который будет транслировать вызовы на сам объект и возвращать полкченный результат и, кроме, делать что-то до/после(/вместо) получения результата от самого проксируемого объекта (в частности, логгирование или управление транзакциями).

              С вызовами функций такая фишка проходит, с обращением к полям — нет.
                +2
                Ну это, насколько я понял то, что вы сказали, относиться к полиморфизму и композиции, а инкапсуляция тут не нужна.
                  –2
                  Полиморфизм без инкапсуляции тоже невозможен, это ж очевидно. Какая полиморфность у полей? У геттеров-сеттеров — да, у полей — нет.

                  Инкапсуляция вынуждает использовать методы. Потом эти методы можно переопределить и(ли) обынтерфейсить.
                    0
                    Проксирование является частным случаем инкапсуляции. Скрываем реализацию настолько что становится всё равно реализация в данном объекте или вообще во внешнем сервисе.
                      0
                      В данном случае, инкапсуляция — технология посредством которой реализуется проксирование, и все-же проксирование не является частным случаем инкапсуляции. Более того, инкапсуляция, сама по себе не означает скрытие, это одна из его возможностей.
                  0
                  Если кратко, имелось в виду проксирование свойств, точнее, геттеров и сеттеров.
                    +1
                    Проксирование, в частности, возможно и без инкапсуляции. Просто то утверждение выглядит так, будто не имеет смысла.
                  +5
                  Во время чтения статьи меня не отпускало чувство, что статья посвящена некоторым аспектам функционального программирования (возможно, с типами).
                  Серьёзно:
                  Сначала объясняется важность интерфейсов, мол, алгоритмы должны быть абстрагированы по-максимуму, поэтому используем интерфейсы вместо конкретных реализаций, классов.
                  Потом четко выделяется мысль «у функции не должно быть скрытого аргумента this, все аргументы равноправны».
                  Потом доказывается, что работать с неизменяемыми типами удобнее, чем с теми, которые имеют своё внутреннее состояние.

                  Автор как-бы подводит нас к замечательной мысли: не стоит нагружать объект лишним сложноконтролируемым поведением. Гораздо приятнее использовать неизменяемые типы данных, фабрики для их генерации и функции, свободные от this, для обработки.
                    +1
                    Да, похоже к этому и идет. И получается, что от ООП мы постепенно вернемся к тому же пресловутому struct/record. Смысла в этом не много, разве что многопоточные приложения будет проще разрабатывать :)
                      +1
                      Для domain objects — да: «проксируемые structs» и сервис-объекты. Но, кроме «доменщины», описывающей реальный мир, существуют библиотеки подпрограмм: в них ОО-парадигма служит способом более компактной, удобной и читабельной организации кода. Об этом я написал только последний абзац;-)
                        0
                        >>Но, кроме «доменщины», описывающей реальный мир, существуют библиотеки подпрограмм
                        С этим утверждением я согласен. Главное, чтобы те, кто «знает доменщину» не начали говорить «я, наверное, знаю ООП». ООП — все-таки больше тяготеет к способам организации архитектуры сложных систем (в вашей интерпретации «к библиотекам подпрограмм», хотя я с этой формулировкой не согласен). ООП — способ организации, структурирования сложной логики, способ хоть как-то контролировать того монстра с тысячей щупалец, в которого может превратиться любой даже самый примитивный код после последовательной реализации нескольких новых (непродуманных изначально, а иногда и противоречивых) требований пользователей. Если в логику приложения гармонично вписывается еще и доменщина — что ж, так тому и быть. Но все-таки ООП сделано ради представления сложной логики в виде набора каких-то относительно независимых, комбинирующихся между собой кусочков с хитрой логикой (т.е. поведением) внутри, а не ради представления class Person (Fio, Birthday, Sex), Company (Name, Address, INN).
                      0
                      А со строгим отделением модели от контроллера в MVC-паттерне ассоциаций не возникает?
                      +5
                      Всё равно много несогласованностей получается.

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

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

                      В-третьих, ООП всё-таки относится к реализации или к проектированию? Мне то всё равно, но при любом из вариантов найдётся куча тех, кто не согласится.

                      В-четвёртых, если объекты — это просто структуры, то чем являются менеджеры?

                      Ну и т.д.

                      Отдельно про типизацию. В OCaml вы не имеете права даже складывать целые числа с дробными. Это — строгая типизация. В Haskell по сути нет возможности привести один тип к другому. Это тоже строго. В Java и подобных языках, где правила языка не только разрешают, но и поощрают передачу одного объекта (потомка) вместо другого (предка), назвать типизацию строгой у меня язык не поворачивается.
                        –1
                        Насколько я знаю, то язык строго типизирован, если невозможно даже явное присваивание типов, не? В С-подобных языках она не строгая, но статическая. В ПХП там ваще фиг знает что, поскольку сначала мона объявить переменную как стрингу, а потом без замарочек и явного привидения присвоить ей интеджер.
                          0
                          Строгость типизации — это относительное понятие. Например, кроме упомянутого OCaml все известные мне языки позволяют (и обычно сами делают) преобразование из целочисленных типов в дробные.
                            +1
                            Язык может заставлять явно преобразовывать типы. Может делать это сам неявно.

                            Важно знать типы на этапе компиляции, это делает язык пригодным для «дешёвого» и интенсивного рефакторинга.
                              0
                              Ну так наследование как раз и обеспечивает незнание конкретного типа на этапе компиляции.
                                +1
                                Конкретного. Достаточно знания некоего над-типа или интерфейса, чтоб код можно было рефакторить.
                                  +2
                                  Что значит «чтоб код можно было рефакторить»? Я свой код рефакторю вообще без использования ООП.
                                  Т.е. у меня есть подозрение, что вы имеете ввиду, но лучше сами озвучьте.
                                    0
                                    Я прежде всего имел в виду пригодность для полуавтоматического рефакторинга средствами IDE, что в разы увеличивает объём кода, которым можно управлять в одиночку.

                                    А что вы подозревали, что я имею в виду?
                                      +1
                                      А, не, я про рефакторинг содержимого классов и всё такое подумал.

                                      Но типизация, всё-таки, нужна не для рефакторинга средствами IDE в первую очередь, а в первую очередь для защиты от ошибок.
                                    –1
                                    А наследование почему отнесли к «bad practice»?
                                0
                                Строгость, по-моему, понятие абсолютное — никаких неявных преобразований типов. В Java/C#/… типизация сильная, но не строгая.
                                  0
                                  Ээ, а под сильной типизацией вы что подразумеваете?
                                  В Scala типизация считается гораздо более строгой, чем в Java, однако неявное преобразование типов там разрешено языком (см. implicit).
                                    0
                                    Скит об этом писал: у «сильной» типизации проблемы с формальным определением. Есть люди, которые считают, что язык, позволяющий любые преобразования типов, уже не является сильно типизованным.

                                    Для сравнения, вот его определение для C# первой версии:

                                    C# 1’s type system is static, explicit, and safe.
                                      0
                                      Сильная накладывает сильные ограничения на преобразования типов, сильные, но не абсолютные. Сильная/слабая имеет градации, можно говорить что в одном языке сильнее, в другом слабее. Строгая же не имеет — триггер, либо строгая, либо нет.
                                        0
                                        Сформулирую вопрос по-другому: чем сильная типизация отличается от строгой?
                              0
                              "...DB-persistence-платформы, в которых логика чтения/записи БД находилась в методах самих персистируемых классов, из-за чего они должны были наследоваться от специального класса типа какого-нибудь DBExternalizableObject. В последствии, «как известно», от этого отказались."

                              Не согласен, что отказались. С появлением скриптовых языков на Java машине у доменных объектов снова появляются методы типа «search», «save» и т.д. Посмотрите например Grails или Spring Roo. Т.е. в зависимости от подключаемого плагина доменные объекты втихоря приобретают много новых методов. И хотя я против такого «супер-быстро-гибкого» подхода, но тем не менее данный принцип, я считаю обрёл второе дыхание и активно популяризуется. Возможно благодаря тому, что наследоваться в данных случаях уже не всегда обязательно.
                                +1
                                Если метод можно прицепить к объекту в runtime-е, а не на этапе проектирования, то это уже не tight coupling. Правда, в нагрузку это ещё и не рефакторится.
                                  +1
                                  Посмотрел Grails. С точки зрения «джависта» — «полный угар»: методы, котрые являются методами экземпляра у CriteriaBuilder и EntityManager, перобразованы в статические методы у сущностей. Как будто все сущности наследуют от одного предка. Ну еще и прикопипастнуты методы (или пригенерированы по шаблону), вызывающие методы предка с доп.аргументом — классом:
                                  public class Person extends DBExternalizableBase{
                                  ...
                                    public static Person get(int id){
                                      return DBExternalizableBase.<Person>get(Person.class, id);
                                    }
                                  ...
                                  }

                                  Вкурил дальше — так и есть, делается через препроцессор. От препроцессора в самой Java отказались сразу. Посмотрел дальше — никакой переносимости кода между библиотеками или между контейнерами даже и не подразумевается, что для программирования на самой Java моветон вдвойне.
                                  –2
                                  Полезная статья, может казаться что все знаешь. А начинаешь читать, и начинаешь искать в поисковике слова которые не знаешь, и понятия чтобы продолжить чтение.
                                  Спасибо остался доволен.
                                    –4
                                    Тем, кто говорит что не умеет программировать в ООП-стиле, нужно попрограммить на С-89 пару неделек. Сразу появится тяга к ООП, поймут зачем создавались инкапсуляция, полиморфизм и наследование.
                                      +3
                                      Сама фраза лишена смысла, а подразумеваемый посыл показывает, что вы не читали или не поняли оригальную статью.
                                      Я, кстати, на C программировал гораздо больше пары неделек. 2 вещи, которые угнетали, это отсутствие модулей/неймспейсов и необходимость вручного освобождения ресурсов. Обе задачи к ООП ортогональны.
                                        –3
                                        я понял смысл статьи (если вы про «Я не знаю ООП»). Может, не совсем верно выразился в комментарии, но смысла это не меняет — с тем же успехом можно писать статьи «Я не умею программировать» и расуждать в них о сферических конях вместо того, чтобы писать код. Какого ты тогда программист, если не умеешь программировать?

                                        Да и вообще, ООП приписывают какую-то мифическую сложность. ООП — вполне естественная эволюция, причём появился он очень давно, почему кто-то столько рассуждает на эту тему — не пойму. Может вы подскажете?
                                          +4
                                          А можно, я подскажу?

                                          По этому поводу рассуждают по двум причинам. Во-первых, начиная с какого-то момента начинают раздражать евангелисты, которые считают, что ООП — не просто естественная эволюция, а верх этой эволюции, а все остальные подходы заведомо хуже. Во-вторых, точно так же раздражают евангелисты, которые утверждают, что ООП — это просто и понятно (особенно смешно, когда в пример этого приводят design patterns). Просто? Понятно? Паттерн «Визитер» — это просто и понятно?
                                            –2
                                            Вы путаете понятия. ООП — это концепция, парадигма, а паттерн это реализация архитектуры. Интегралы. Просто? А численное интегрирование дифференциальных уравнений сплайнами? Уже не так просто и понятно?
                                              +3
                                              Простите, а что я и с чем путаю? Это евангелисты ООП регулярно приравнивают паттерны к достижениям ООП.
                                                0
                                                Просите, неверно истолковал ваш комментарий. Подумал, что вы в пример сложности ООП приводите некоторые паттерны.
                                              0
                                              Design patterns — это «Think Haskell, code C++».
                                                0
                                                Простите, это ваше высказыванеи для меня слишком умно. Не могли бы вы его пояснить?
                                                  0
                                                  Реализация высокоуровневых черт в низкоуровневыз языках. В 1950-е годы, ещё до изобретения стека и немного после него, на ассемблере некоторых машин вызов подпрограммы тоже был «шаблоном дизайна».
                                                    0
                                                    Получается, все современные ОО-языки — низкоуровневые?
                                                      –1
                                                      Java и С++ по сравнению с Javascript, LISP и Haskell — да.

                                                      Уточню свой ответ — это сейчас в основном реализация черт функциональных языков в языках, в которых функция не является «объектом первого класса».

                                                      недавно нашёл — norvig.com/design-patterns/ или www.google.com/search?q=peter+norvig+design+patterns+in+dynamic+languages
                                                        +2
                                                        … и при этом паттерны традиционно считаются сильной стороной ООП.

                                                        Феерическая логика.
                                                          +2
                                                          Кем считаются? Не мной точно. Паттерны — это по определению «костыли», раз можно не только «так», а ещё и «не так», раз можно, например, не только «собирать мусор», а ещё и «не собирать мусор». Лучший паттерн — это элемент синтаксиса языка, как оператор вызова функции или оператор цикла или интерфейс в Java. Второй — это системная библиотека, подпрограмма или макрос, которые вынуждают его использовать, типа ситуации с ActionListener-ами в Java. Третий — несистемная библиотека, подпрограмма или макрос, которые вынуждают его использовать.
                                                            0
                                                            Лучший паттерн — это элемент синтаксиса языка, как оператор вызова функции или оператор цикла или интерфейс в Java.

                                                            Это не паттерн, это идиома.
                                                              +1
                                                              Лучший паттерн — это идиома.
                                                                +1
                                                                Я понимаю, что это звучит демагогично, но когда для некоего поведения есть идиоматическая реализация, паттерны как-то не нужны уже.
                                                                  +1
                                                                  Согласен. Если для некоего частого поведения требуется паттерн, значит, в языке не хватает идиом или библиотечных функций/макросов. Паттерны — это костыли для хоть какого-то лечения этой нехватки.
                                                            0
                                                            и при этом паттерны традиционно считаются сильной стороной ООП.
                                                            Попытаюсь найти точку зрения, с которой это так.

                                                            Раз паттерны — неизбежное зло, будем использовать. И тут — да, в ОО языках и сами эти костыли красивее и пользы от них больше, чем в не-ОО языках. «Think Haskell, code C++», образно говоря, лучше, чем «Think С, code very bad assembler».
                                                              0
                                                              Меня удивляет, что вы не видите паттернов класса «Think F#, code C#».
                                                +3
                                                Нет, смысла статьи вы так и не поняли. ООП сейчас — это размытый набор понятий, половина из которых в равной степени принадлежит и другим парадигмам, а вторая половина считается bad practices. Так что прежде, чем делать выводы, попробуйте сами сформулировать, что такое ООП. А потом почитайте комментарии к той статье и посчитайте, сколько людей с вами не согласятся.

                                                Про эволюцию — тоже глупость. Появление любой новой парадигмы — эволюция, тотальный переход к одной парадигме — просто ветвь развития с неопределённым будущем.
                                                  +1
                                                  ООП — это, как к сегодняшнему моменту выяснилось, прежде всего полезная технология оптимальной организации кода, позволяющий в одно лицо менеджить в десять-сто (за счёт сторонних open-source библиотек) раз бОльшую функциональность и быстрее «въезжать» в чужой код. А описание каких-то там объектов реального мира и их взаимоотношений — это, как мне тут объяснили, лирика и процентов 5 от общего объёма.
                                                    +2
                                                    За оптимальную организацию кода отвечает модульность (в любом проявлении, будь то непосредственно модули, как Python, пакеты, как в Common Lisp или неймспейсы, как в C++), а наличие большого количества библиотек зависит от области — попробуйте найти хорошие ООПэшные библиотеки, например, для математики или статистики.
                                                      0
                                                      Ну, приватные члены в ООП (где они есть) — это в том числе и вариант «модульности для бедных».
                                                        +1
                                                        Да дело не в приватности членов — приватность можно хоть на уровне конвенций организавать — дело в хорошей декомпозиции кода. И такие языки, как Python или Oberon, например, позволяют гораздо лучше структурировать и организовать код, чем та же Java, в которой вы вынуждены каждый независимый кусок функционала выносить в отдельный файл. Тогда мы возвращаемся к вопросу: если ООП — это не описание объектов реального мира и не возможность оптимальной организации кода, то что это? Зачем оно надо?
                                            +1
                                            В частности, предпочтительным способом реализации сущности «социальный аккаунт» для программы, работающей с разными социальными сетями, является не создание абстрактного класса SocialAccount с потомками FBAccount, VKAccount и TwitterAccount, а создание нормального domain class’а SocialAccount и фабрик-конвертеров в него из данных от разных социальных сетей, может быть даже JSON-to-SocialAccount-конвертеров.

                                            Простите, а можно это мнение как-то обосновать, что ли?
                                              0
                                              1) борьба с tight coupling-ом, в этом случае борьба в виде «принципа единственной ответственности» — не грузить класс доменной сущности доп.функцией «дешифровки» REST-ответов.
                                              2) если у API выйдет новая версия, то ещё один класс «дешифратора» будет смотреться лучше, чем ещё один класс доменной сущности для той же социальной сети. А если ещё ввели явное или неявное или архитектурное ограничение, что у одной социальной сети может быть только один класс социального аккаунта, то такое внешнее нововведение вообще поломает архитектуру пирложения.
                                                0
                                                Угу. Ваш ответ наглядно показывает «думали одно, написали другое». Очевидно, что потомки FBAccount, VKAccount и так далее реализуют в себе специфическую функциональность, связанную с учетными записями (фолловеры, персональная информация, фотографии, лайки и так далее), а общение с API конкретной социальной сети в любом случае лежит отдельно (паттерн Бридж машет нам всем лапкой). По большому счету, это типичное такое persistance ignorance, только расширенный до service ignorance.
                                                  0
                                                  В пользу FBAccount и VKAccount гоорит в основном то, что в экземпляре можно хранить сырой REST-ответ и не запрашивать сервер лишний раз.

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

                                                  Persistence ignorance (видимо, это .NET-специфичный термин, в Java я его не встречал) — это хорошая и правильная вещь.
                                                    0
                                                    В пользу FBAccount и VKAccount гоорит в основном то, что в экземпляре можно хранить сырой REST-ответ и не запрашивать сервер лишний раз.

                                                    Эмм… а зачем?

                                                    Мы с вами явно говорим о вообще разных задачах, которые, как следствие, приводят к разной декомпозиции (снова привет простому и понятному ООП).

                                                    Persistence ignorance (видимо, это .NET-специфичный термин, в Java я его не встречал) — это хорошая и правильная вещь.

                                                    Вообще-то, это термин из архитектуры.
                                                      0
                                                      Persistence ignorance (видимо, это .NET-специфичный термин, в Java я его не встречал) — это хорошая и правильная вещь.
                                                      Вообще-то, это термин из архитектуры.
                                                      Погуглил. В википедии его нет, в интеренте встречается только в текстах про .NET и связанных с ним платформах. Похоже, что это — специально изобретённый Микрософтом велосипед. Брендинг и нейминг — тоже важные вещи.
                                                        0
                                                          0
                                                          Связано с .NET.
                                                            0
                                                            Особенно Фаулер. Впрочем, это не важно. Принцип остается принципом.
                                                              0
                                                              «Из переписки Энегельса с Каутским»;-) В том посе Фаулер предложил этот термин в ответ на вопзрос именно по тематике связанной с .NET в противовес термину POCO — .NET-овской кальке с POJO.
                                                          0
                                                          Не говоря о том, что это, на самом деле, не термин, а концепция, и она описана Фаулером (без конкретного термина) в PoEAA, шаблон Data Mapper.
                                                            0
                                                            Это именно термин. В Java та же самая концепция называется термином POJO.
                                                              0
                                                              Не совсем.

                                                              POJO/POCO — это использование «обычного» объекта, не отягощенного, например, базовым классом, компонентами и прочей не нужной в домене фигней.

                                                              Persistence ignorance — это тот факт, что объект ничего не знает о своем сохранении. Он при этом может не быть POCO/POJO (например, если это компонент); а с другой стороны, POCO/POJO может быть persistence-aware, если в нем есть методы, которые кладут его в базу и достают оттуда.

                                                              Но это весьма тонкие нюансы, в среднем POCO/POJO действительно являются *-ignorant.
                                                +8
                                                Я, наверное, знаю ООП

                                                Нет, не знаешь.
                                                  +4
                                                  С появлением «методов» всплыл ещё один приятный момент в части организации функционала: вместо создания 900 функций с перекрёстно дублирующимися первыми и вторыми половинами названий (помните WordBasic?) можно сделать 30 классов с 30 методами в каждом.


                                                  Это заслуга ООП? Нет. Чем это лучше 30 функций в 30 модулях?

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


                                                  Строгая типизация тоже заслуга ООП? Да, ну, ладно, посмотрите на OCaml и Haskell. И не надо приписывать все на свете к «великим достижениям ООП».
                                                    0
                                                    Не понимаю такого большого количества минусов к статье, согласен практически со всем. Причем несмотря на название на самом деле она полностью подтверждает все мысли поста пользователя ffriend. Современное ООП совсем не такое, как в примере про печь пользователя veitmen и прочих других примеров из разных книжек об ООП.
                                                      0
                                                      Ой ой ой… Меня то сюда зачем? :(

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

                                                      Но, если вы имеете ввиду то, что печи не используются в вашем ПО, то — да, у меня тоже, к сожалению. :(
                                                        0
                                                        Сюда Вас за тем, что Вы писали ту статью, так сказать подбросили говен на вентилятор продолжили эту ООП перепалку.

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

                                                        А на счет того, в каком ПО используется то, что Вы описывали, то я готов принять ссылку на любой OpenSource проект, где есть тот ООП, о котором Вы говорите. Мне действительно интересно.
                                                          –2
                                                          Прочитал до менеджеров, которые помогут сделать грязное дело. Понял что человек не понимает что такое принцип единственной обязанности (или как его еще часто называют принцип единственной ответственности). Дальше не буду.

                                                          Какое «такое» ООП у меня? Правильно используемое? Или что? :) Или вы что-то другое имеете ввиду? Просто из ваших слов я понял что мое ООП плохое и не используется, а то, о котором говорит автор — хорошее. Но то, что автор опять не понимает что говорит, мы в расчет брать не будет?

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

                                                          По поводу ООП. Прежде чем говорить что это говно, научитесь его использовать и научитесь мыслить объектно. Научитесь проектировать и программировать используя ООП. Как я уже говорил одно без другого бессмысленно использовать! Но то, что вы не видите ляпы автора (авторов), говорит лишь о том, что вы нихрена не понимаете что такое ООП.

                                                          И да, я не хочу спорить на тему ООП. Мне надоело. Люди будут еще очень долго кричать что ООП зло. Но чаще всего, это связанно с тем, что они не понимают его и пытаются всему миру доказать, что это не у них не получается, это ООП такое стремное. Понимаете?
                                                            +1
                                                            Прежде чем говорить что это говно, научитесь его использовать и научитесь мыслить объектно. Научитесь проектировать и программировать используя ООП.

                                                            Я знаю, ООП скоро объявят религией, а любое инакомыслие будет жестоко наказаваться инквизицией. Программисты на Haskell/Erlang/Lisp/Clojure/etc будут гореть в аду за прегрешения и нежелание познавать «О великую истину ООП». Детский сад, ей богу.

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

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

                                                            ООП это не верх эволюции мышления программистов, там многое притянуто «за уши». А фразы типа «вы сначала научитесь, а потом тут рассказывайте» вообще лишены смысла. С тем же успехом я могу сказать: Научитесь писать на функциональных языках, изучите и познайте теорию категорий, и да возрадуйтесь монадам ибо это хорошо, и да не использованы будут мутабельные данные и не настигнет нас гневный race condition, и принесите функцию в жертву функтору аппликативному и да соблюдите чистоту в функциях порядка высшего… и вот уже тогда пишите нам о том, что такое ООП и какое оно прекрасное (если, конечно, захочется).
                                                              –2
                                                              Да нет. Фарс создали вы.
                                                              А фразы типа «вы сначала научитесь, а потом тут рассказывайте» вообще лишены смысла.
                                                              Да конечно вы правы. Давайте рассказывать и писать обо все чего не знаешь. Будет супер! То, что для вас это лишено смысла, еще раз говорит о том, что вы любитель потрепать на неведомые вам темы.

                                                              А то, что автор не понимает чего пишет, и судя по всему вы тоже не понимаете. И именно на это указал я, как факт того, что автор «плавает» и вы тоже, раз этого не видите.

                                                              Я знаю, ООП скоро объявят религией, а любое инакомыслие будет жестоко наказаваться инквизицией. Программисты на Haskell/Erlang/Lisp/Clojure/etc будут гореть в аду за прегрешения и нежелание познавать «О великую истину ООП». Детский сад, ей богу.
                                                              Никогда ничего не сказал плохого про другие подходы, которые не ООП. Всегда говорю лишь, что ООП — это универсальный и очень мощный инструмент. Детский сад прет из вас, т.к. вы видите в моих словах придуманное вами.

                                                              Как по мне, то основная причина столь долгих споров заключается в следующем: в комментариях ко всем статьям приводятся указания на различные нестыковки, несогласованности, «непонятностях» в парадигме.

                                                              Как по мне, то основная причина столь долгих споров заключается в следующем: в комментариях ко всем статьям приводятся указания на различные нестыковки, несогласованности, «непонятностях» в парадигме.
                                                              Повторюсь. У автора статьи, нестыковки происходят из-за того, что он не умеет использовать инструмент. Конкретно это видно, когда человек забыл про принцип единственной обязанности. И это еще раз подтверждает мои слова:
                                                              Но чаще всего, это связанно с тем, что они не понимают его и пытаются всему миру доказать, что это не у них не получается, это ООП такое стремное.
                                                                +1
                                                                Давайте не переходить на личности, это грубо и некрасиво. Я не оценивал ничьи знания (ни автора статьи, ни ваши), поэтому прошу вас не оценивать мои. и не тыкатать меня носом в то, что я вижу, а чего нет (у вас для этого нет никаких оснований).

                                                                Я согласен с комментариями
                                                                habrahabr.ru/post/149096/#comment_5038319
                                                                habrahabr.ru/post/149096/#comment_5038093
                                                                и не буду приводить здесь свои рассуждения, дабы не повторяться. Если вы считаете, что исчерпывающий ответ на эти комментарии — «человек забыл про принцип единственной обязанности», то пусть так и будет. Собственно об этом и был мой предыдущий комментарий.
                                                                  –2
                                                                  Если вы считаете, что исчерпывающий ответ на эти комментарии — «человек забыл про принцип единственной обязанности», то пусть так и будет.
                                                                  Не надо все под одну гребенку. Везде свои проблемы и ответы.

                                                                  Давайте не переходить на личности, это грубо и некрасиво.
                                                                  Я этого не понимаю. Я не говорю, что автор злой и некрасивый. Я говорю, что автор не понимает чего пишет и конкретно указываю что не понимает! И говорю, что вы тоже, раз поддерживаете автора и считает статью дельной. Или теперь нельзя говорить что именно вы неправы??? Вы может быть очень добрый и хороший человек, и другого я не смею думать.
                                                                    +1
                                                                    Я этого не понимаю.

                                                                    Жаль.
                                                                    И говорю, что вы тоже, раз поддерживаете автора и считает статью дельной.

                                                                    Неправда. Читайте, пожалуйста, внимательно habrahabr.ru/post/149096/#comment_5039788
                                                                    Или теперь нельзя говорить что именно вы неправы

                                                                    Можно, с радостью выслушаю аргументированное объяснение. Именно аргументированное. А вот ваши высказывания:
                                                                    вы любитель потрепать на неведомые вам темы

                                                                    автор не понимает чего пишет, вы тоже не понимаете

                                                                    автор «плавает» и вы тоже, раз этого не видите

                                                                    это не аргументы. Это просто персонолизированные оценочные высказывания (ничем не подтвержденные), к тому же высказанные слишком уж надменным тоном. Ввиду этого считаю дальнейший разговор бессмысленным.
                                                                      0
                                                                      Я же вам конкретно говорю:

                                                                      Прочитал до менеджеров, которые помогут сделать грязное дело. Понял что человек не понимает что такое принцип единственной обязанности (или как его еще часто называют принцип единственной ответственности).
                                                                      Или это не аргумент?
                                                                        –2
                                                                        Это просто персонолизированные оценочные высказывания (ничем не подтвержденные), к тому же высказанные слишком уж надменным тоном.
                                                                        Это выводы.

                                                                        Аргумент — автор не знает что такое принцип единственной обязанности и поэтому не понимает зачем создавать другие абстракции (его пример с менеджерами отличное подтверждение моих слов). Используя этот аргумент я с уверенностью заявляю что автор «плавает» в теме. И если вы любитель использовать чужое мнение, то я тоже сейчас это сделаю.
                                                                        habrahabr.ru/post/149096/#comment_5042923
                                                                        habrahabr.ru/post/149096/#comment_5039559

                                                                        Далее, путем несложных умозаключений я прихожу к выводу что вы тоже «плаваете», раз считаете статью дельной.
                                                                          0
                                                                          Ну… Опять вы за свое. В ваших логических рассуждениях есть одна очень большая проблема — они основаны на неверной предпосылке. И я вам на это указал явно. Почему вы не хотите этого понять?

                                                                          Давайте еще раз. Я писал,
                                                                          И говорю, что вы тоже, раз поддерживаете автора и считает статью дельной.
                                                                          Неправда. Читайте, пожалуйста, внимательно habrahabr.ru/post/149096/#comment_5039788

                                                                          Вы же продолжаете твердить
                                                                          вы тоже «плаваете», раз считаете статью дельной.

                                                                          Я выделил ошибочное суждение, дабы вам было в этот раз попроще. Я не написал ни одного комментария в поддержку статьи либо ее автора. Приведенный вами аргумент — вымысел.
                                                                            +1
                                                                            Ой. Прошу прощения! Я просто думал что это вы написали:
                                                                            habrahabr.ru/post/149096/#comment_5041790

                                                                            Я дико извиняюсь!!! Я забираю свои слова обратно! Высказывания были не в ваш адрес! Я думал что продолжаю общаться с тем человеком. Прошу прощения за невнимательность. :(
                                                                            0
                                                                            автор не знает что такое принцип единственной обязанности и поэтому не понимает зачем создавать другие абстракции (его пример с менеджерами отличное подтверждение моих слов)

                                                                            Мы точно одну и туже статью обсуждаем? Автор то как раз знает, что это такое, ну пусть называет это скажем более старомодно, что не должно быть «tight coupling», как у Тома ДеМарко, а не SRP, как Роберта Мартина.
                                                                              0
                                                                              SRP — более конкретный и более красиво выглядящий аргумент для троллинга плохой архитектуры, чем более общий «loose coupling»;-)
                                                                                0
                                                                                Гм. А ничего, что SRP и Coupling вообще никак не связаны? Cohesion еще как-то связан, а вот coupling — вообще никак.
                                                                                  0
                                                                                  Ваша правда, наличие разнородных обязанностей внутри одного модуля это нарушение «High Cohesion».
                                                                                    +1
                                                                                    Cohesion и Coupling — это термины, в которых описыватся картинки, видимые с разных сторон — responsibilities и архитектуры. Low cohesion — это всегда tight coupling.
                                                                                      0
                                                                                      Ась?

                                                                                      Возьмем операции с БД. Есть два объекта, книги и авторы, для каждого из них есть стандартный CRUD.

                                                                                      Поступим как идиоты, и реализуем каждый из них в отдельном классе. Сервисный слой смотрит на каждый класс напрямую, инстанциируя его при вызове. Что получили? Tight coupling, потому что сервис знает обо всех, low cohesion, потому что работа с одним объектом «размазана».

                                                                                      Окей, мы начитались книжек про DI, и сделали для каждого класса интерфейс (а то и generic-интерфейс), и сервис стал получать эти интерфейсы через вбрасывание. Что стало? Loose coupling, потому что сервис знает только об интерфейсах, а вот cohesion не изменился, потому что логика как была размазана, так и осталась.

                                                                                      Окей, мы прочитали книжку про overarchitecture, выбросили интерфейсы, слили весь DAL в один класс. Tight coupling (сервис опять знает о DAL), high cohesion (все в одном месте), заодно нарушение SRP (один класс занят двумя не связанными обязанностями).

                                                                                      Вообще, о cohesion очень хорошо написано в Code Complete. Заодно становится понятно, что у этого параметра есть несколько разновидностей, и часть из них является признаком хорошего дизайна, а часть — признаком плохого.
                                                                                        0
                                                                                        Вот отсюда — en.wikipedia.org/wiki/Cohesion_(computer_science)#High_cohesion — можно заключить, что cohesion — это мера того, насколько связаны функциональности, заключённые в одном модуле, и она в общем не связана с тем, по скольким классам или модулям эта функциональность размазана.
                                                                                          0
                                                                                          Да, вы правы, а мой пример в этом месте некорректен. Но это не отменяет того факта, что coupling и cohesion ортогональны.
                                                                  +1
                                                                  Про плохое/говно/прочие эмоции это Вы сами придумали, оно хорошее, но проблема в том, что ООП, о котором Вы говорите сугубо сферическо-теоретическое.
                                                                  Впрочем спорить я тоже не хочу, всего лишь прошу пример проекта, где нет никаких менеджеров, а бизнес логика построена на одних доменных объектах.
                                                                    –2
                                                                    :) А вы думаете что использование менеджера это зло? :) Я так не считаю. Это разделение ответственности. Кто-то сеет, кто-то жнет, кто-то подает. Меня доставать начинает, что менеджеры, в тех или иных проявлениях считаются злом.
                                                                      +2
                                                                      Я то как раз так не думаю.
                                                                      С появлением менеджеров бОльшая часть поведения объектов уходит в менеджеры, а сами объекты вырождаются просто в контейнеры данных. И как результат в реальных проектах не бывает того, о чем Вы пишете:
                                                                      Есть печь (абстрактная печь). У нее есть поведение — включить, выключить, увеличить или уменьшить температуру, положить чего-то, достать чего-то и состояние — температура в печи, включена или выключена. Это отличный пример абстрактного объекта в котором соблюдены принципы инкапсуляции (при реализации я их обязательно буду соблюдать).

                                                                      но когда об этом говорят, Вы отвечаете:
                                                                      научитесь его использовать и научитесь мыслить объектно
                                                                        –1
                                                                        Да, и сейчас повторю. Проблемы в том, что разделение поведения и состояния не страшны и не противоречат ООП. Вопрос абстракции и не более.
                                                                          –1
                                                                          Ай.

                                                                          Проблемы в том, что разделение поведения и состояния не страшны и не противоречат ООП = Разделение поведения и состояния не страшны и не противоречат ООП. Нет тут проблемы!
                                                                          0
                                                                          Пускай будет печь. Которая обладает ток состоянием. И Пекарь который меняет это состояние. Если для решения моих задач такая абстракция нормальна, то проблемы нет.
                                                                            0
                                                                            Да, вот это уже ближе к правде, но соль в том, что у пекаря то нет состояния, только поведение.

                                                                            PS: а если совсем по занудствовать, то в итоге мы получили отдельно структуру данных печь и пространство имен «пекарь» с функциями реализующими поведение пекаря.
                                                                              0
                                                                              Ну нет состояния и что? :) Если для решения задачи в моей абстракции не нужно состояние, то разве это проблема? Объект пекарь то есть, который умеет печь. И он будет именно тем менеджером о котором все говорят. И хуже нам жить не стало. :)
                                                                                0
                                                                                Если у нас программа состоит из классов без поведения ( = структур) и менеджеров без состояния ( = модулей), то в чём состоит объектная ориентированность данного кода?
                                                                                  –2
                                                                                  А вы сейчас опять начнете говорить, что понятие объекта было придумано не в рамках ООП. И то, что проектирование с использованием объектов и их взаимодействия это тоже не имеет никакого отношения к ООП. Проходили.
                                                                                    +2
                                                                                    И какое это имеет отношение к моему комментарию? Речь о том, что описанный вами подход не является объектно-ориентированным. Т.е., например, есть 2 аналогичные программы, одна на Java, вторая на Oberon. В программе на Java используются объекты, несущие состояние, и один обеъект-синглтон-менеджер, выполняющий действия. В программе на Oberon есть records, несущие состояние, и один модуль, выполняющий действия. Почему программа на Java будет объектно-ориентированной, а программа на Oberon — нет?

                                                                                    Вы, конечно, можете сказать, что программа на Oberon тоже будет объектно-ориентированной, обосновав это, например, всё тем же взаимодействием объектов, но тогда альтернативный вопрос: если ООП настолько всеобъемлюще, что покрывает собой и другие парадигмы, то в чём вообще отличие ООП от программирования в принципе?
                                                                                      0
                                                                                      > если ООП настолько всеобъемлюще, что покрывает собой и другие парадигмы, то в чём вообще отличие ООП от программирования в принципе?

                                                                                      Ого, вот это действительно заслуживает восхищения! Спасибо, вы сделали мой день.
                                                                                        0
                                                                                        Вы забываете что есть проектирование с использованием ОО подхода, а есть программирование с использованием ООП. Так вот, я могу проектировать систему используя ОО подход. При этом, может так получится что я не буду использовать наследование и инкапсуляцию. То, получается, реализовать такую систему не составит труда и не на ООП языке. Верно? Но, если я использую эти инструменты при проектировании, то мне будет тяжело реализовать эту систему в рамках не ООП языка. Понимаете? Нельзя говорить о программировании без проектирования в данном вопросе.
                                                                                        Отсюда я попытаюсь дать ответ на ваш вопрос про Oberon & Java. Если в рамках проектирования используя ООП подход, я не использовал основные инструменты (наследование, полиморфизм), то систему можно реализовать на языке, который не реализует эти инструменты. То, что вы написали код на ООП языке, не говорит о том, что вы использовали ОО подход при проектировании. Отсюда получается что сравнение ваше абсолютно некорректно, я понятия не имею как вы проектировали систему и какой подход использовали при разработке ПО.
                                                                                        Резюмируя: использование языка, не говорит о том, использовал ли я ОО подход при проектировании. Следовательно можно писать не ОО программы на ОО языке. И можно писать ОО программы на не ОО языке, только написать будет практически нереально, особенно если я использую все инструменты ООП при проектировании.

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

                                                                                          Если в рамках проектирования используя ООП подход, я не использовал основные инструменты (наследование, полиморфизм)

                                                                                          Я ещё раз спрашиваю: в чём тогда состоит этот «ООП подход»? Чем он отличается от модульного программирования?
                                                                                            0
                                                                                            Я ещё раз спрашиваю: в чём тогда состоит этот «ООП подход»? Чем он отличается от модульного программирования?
                                                                                            о.О
                                                                                            Вы меня шокируете с каждым разом все больше. :) Сравнить такие вещи… Это ирония? Я надеюсь что да. Иначе это полный п…

                                                                                            И да, прежде чем негодовать по поводу моих слов выше, задайте себе хотя бы эти два вопроса:
                                                                                            1. Можно ли сделать модуль с использованием ООП?
                                                                                            2. Можно ли сделать два модуля на разных языках?

                                                                                            И когда ответите на них, подумайте еще раз, что вы сейчас сравнили.

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

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

                                                                                            Резюмируя. Мне кажется хватит. Мне ваши доводы и вопросы кажутся смешными, вам мои. Я стараюсь приводить аргументы, вы тоже. Для меня ваши аргументы кажутся смешными, для вас мои. Я порой перегибал палку, но я достаточно эмоционален и не стыжусь этого. Если обидел, извините. Но порой хочется высказать очень многое. :) Как, например, при сравнении модульного подхода и ООП.
                                                                                              0
                                                                                              Вы еще спросили что же такое ОО подход при проектировании. Это в первую очередь объектное мышление. Вы выделяете объекты и требуемый уровень абстракции этих объектов для решения вашей задачи. А также продумываете то, как объекты будут взаимодействовать.

                                                                                              Что такое «объект» в рамках этого определения?
                                                                                                +3
                                                                                                Вы не приводите аргументы, вы передёргиваете и сами задаёте вопросы, ответы на которые вам кажутся очевидными. А они не очевидны. Терминология неочевидна. Как я уже неоднократно говорил, в современном мейнтримовом программировании нет чёткого определения ООП. Я попросил привести конкретные отличительные черты ООП от других парадигм. Это прострая классификация. Люди делятся на мальчиков и девочек, при этом они отличаются половыми органами, формой лба, голосом и т.д. В биологии выделяют 5 форм жизни, при этом они сильно отличаются формой, структурой клеток, способом питания и дальше по списку. Есть много видов спорта, при этом они отличаются набором задач и используемых движений. В чём состоят отличительные черты ООП? В чём разница между ним и другими парадигмами, а также между ним и проектированием вообще? Вы пока что прыгаете между двумя версиями:

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

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

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

                                                                                                Опустим тот момент, что эти «инструменты ООП» на практике используются редко, речь сейчас не об этом. Речь о том, что эти инструменты и принципы не имеют никакого отношения к подходу, когда функциональность и хранилища данных разделяют (менеджеры + DTO). Например, в таком подходе не используется наследование, следовательно, теряет смысл и LSP. А если принципы парадигмы не соблюдаются, то с какого перепугу вы всё ещё считаете это той же парадигмой?
                                                                                                  +2
                                                                                                  Знаете, ваши комментарии — это тот редкий случай, когда я жалею, что не могу поставить плюс.
                                                                                                    0
                                                                                                    Я делаю всё то же самое при проектировании с любым подходом — функциональным, структурным, модульным, да хоть чисто математическим.
                                                                                                    Ну так вы и используете объектный подход. Вы используете объектное мышление. То, что вы используете объектное мышление при проектировании системы, которая будет реализовываться в функциональном языке (как пример), говорит лишь о том, что вы не верно мыслите, вам надо мыслить другими вещами (например потоки данных, полностью забыв про состояние и понятие объекта, т.к. их там нет :P). Это еще раз лишь подчеркивает то, что вы используете объектный подход там, где надо использовать другие принципы мышления. И это еще раз говорит о том, что объектный подход при проектировании очень удобен.

                                                                                                    В чем отличие других подходов от ООП? На уровне языка — это возможность использования наследования, полиморфизма. На уровне проектирования — использования объектного подхода, плюс возможность использования именно на уровне проектирования наследования и полиморфизма. В других парадигмах вы тоже будете использовать объектный подход, но такая возможность у вас есть благодаря тому, что объектный подход, предложенный ООП, очень прост.
                                                                                                      +1
                                                                                                      То, что вы используете объектное мышление при проектировании системы, которая будет реализовываться в функциональном языке (как пример), говорит лишь о том, что вы не верно мыслите, вам надо мыслить другими вещами (например потоки данных, полностью забыв про состояние и понятие объекта, т.к. их там нет :P)

                                                                                                      Честно говоря, я уже заколебался разбираться в вашей терминологии и в понимании, что является чем. Давайте по порядку.

                                                                                                      1. Что такое объект в вашем понимании?
                                                                                                      2. Является ли поток данных объектом?
                                                                                                      3. Что такое объектный подход/объектное мышление? Почему мы считаете, что использование абстракции и выделения взаимосвязанных сущностей (структур, модулей, функций — чего угодно в программе) — это объектное мышление?

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

                                                                                                      Уровень языка меня в данный момент не волнует — разобраться бы с уровнем проектирования. Про объектный подход уже спросил. Что касается «возможности использования наследования и полиморфизма», возможность использования != использованию. Если у меня есть возможность ограбить банк, это ещё не значит, что я грабитель — грабителем я буду только если действительно ограблю банк. Если у вас есть возможность использовать наследование и полиморфизм, но вы его не используете (а из комментариев видно, что многие их почти не используют), то почему это должно называться ОО проектированием?
                                                                            +1
                                                                            Понял что человек не понимает что такое принцип единственной обязанности (или как его еще часто называют принцип единственной ответственности).
                                                                            У вас создалось впечатление, что в менеджере счетов предлагается совместить функциональность по переводу денег и по персистингу данных в БД?
                                                                              0
                                                                              Ну в каком то смысле оно так и будет :-) Ведь обращение к DAO то будет, а вот детали персистинга уже внутри DAO.
                                                                                0
                                                                                Перевод денег и обращение к DAO для сохранения будет в сервисе (как и управление транзакциями), сохранение — в самом DAO, а коммит транзакции — вообще в контейнере. Правда, иногда ещё и все методы из DAO дублируют в сервисе… тогда получается, что при проектировании web-приложений с ORM SR-принцип нарушается почти всегда, и это такой стандарт.
                                                                                  0
                                                                                  Ну а сервис разве не еще одна вариация на тему менеджеров? А на счет «в каком то смысле так и будет» имел в виду, что все равно где то будет точка, в которой произойдет связывание всех кусочков во едино. А так да, все будет именно так, как Вы описали.
                                                                                    0
                                                                                    Ну а сервис разве не еще одна вариация на тему менеджеров?
                                                                                    Да, ещё одна. В современном стандартном дизайне web-приложений с ORM менеджеров аж три слоя: DAO, сервис и контроллер. С какой-то долей обобщения можно сказать, что вся ответственность — в контроллере, хотя он в основном только дёргает сервисы.
                                                                      +5
                                                                      Мне одному показалось, что у топикстартера каша в голове?..
                                                                        +1
                                                                        При вызове конструктора класса-потомка вначале вызовутся конструкторы всех классов-предков,

                                                                        Типично только для некоторых языков, в других нужно вызывать конструкторы предков «ручками».
                                                                          –1
                                                                          >принцип тут один, в общем, тот же самый, что при проектировании баз данных: представление всего в виде объекта — некоторой штуковины со свойствами.

                                                                          Я не знаю знаете ли вы ООП, но проектированием баз данных вам лучше не заниматься.
                                                                            +1
                                                                            Можно и короче сказать, что вы написали: c2.com/cgi/wiki?MainstreamOopUsage
                                                                              –1
                                                                              Современные domain classes, кроме того, на деле почти всегда являются «прослойкой» к записям в таблицах баз дынных и проектируются изначально в СУБД или в средстве проектирования СУБД.

                                                                              мне кажется, что сейчас часто главное это моделирование прикладной области, которое может является довольно сложной задачей, поэтому проектировать нужно именно модель классов. А куда «лягут» объекты, в реляционную или объектную СУБД, в XML или в другое «хранилище» объектов, это другой вопрос.

                                                                                +1
                                                                                Проектировать нужно модель сущностей. А куда они там лягут — в классы, в БД или в сообщения — другой вопрос.
                                                                                  0
                                                                                  Проектировать нужно модель сущностей. А куда они там лягут — в классы, в БД или в сообщения — другой вопрос.

                                                                                  если мы дискутируем в рамках статьи Автора, посвященной ООП-дизайну, то я не согласен. Позвольте изложить свое
                                                                                  видение:
                                                                                  Начинаем проектирование с определения объектов прикладной области(Domain Objects), они же Бизнес-объекты. Сущности, как Вы написали, определяют при построении концептуальной модели БД. Мы же заходим с другой стороны.
                                                                                  Анализируем прикладную область, строим различные модели, в финале строим модель классов, а уже потом проектируем БД(если мы планируем ее использовать) для сохранения объектов.

                                                                                  Думаю, что концентрация на модели классов очень важна, так как это и есть «ядро» системы(с позиции инженера-программиста), насколько точна и удобна будет эта модель, зависит успех конструирования ПО.

                                                                                    +3
                                                                                    Сущности, как Вы написали, определяют при построении концептуальной модели БД.

                                                                                    Нет. Сущности выделяют при анализе бизнес-процесса.

                                                                                    Анализируем прикладную область, строим различные модели, в финале строим модель классов

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

                                                                                    Думаю, что концентрация на модели классов очень важна, так как это и есть «ядро» системы

                                                                                    Ядро системы очень часто не имеет ничего общего с прикладной областью. И иногда эти два аспекта могут быть реализованы даже в разных парадигмах.
                                                                                      0
                                                                                      Нет. Сущности выделяют при анализе бизнес-процесса.

                                                                                      Вы о какой методике анализа бизнес-процессов говорите?
                                                                                      Я почему решил что Вы про БД, так как термин «сущность» у меня ассоциируется с концептуальной моделью БД.

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

                                                                                      Я ранее писал, что рассуждаю в рамках дискуссии посвященной ООП-дизайну, соответсвенно говорю про декомпозицию методом определения объектов прикладной области.

                                                                                      Пожалуйста объясните фразу «результат проектирования прикладного решения».

                                                                                      Ядро системы очень часто не имеет ничего общего с прикладной областью.


                                                                                      Возможно Вы неправильно меня поняли, я имею ввиду не то, что иногда называют «engine». Я имею ввиду фокусирование инженера-программиста на построении модели классов, для него это «ядро» проекта.

                                                                                      И иногда эти два аспекта могут быть реализованы даже в разных парадигмах.

                                                                                      Простите, Вы здесь о чем?

                                                                                        +1
                                                                                        Вы о какой методике анализа бизнес-процессов говорите?

                                                                                        Ни о какой конкретно.

                                                                                        Я ранее писал, что рассуждаю в рамках дискуссии посвященной ООП-дизайну, соответсвенно говорю про декомпозицию методом определения объектов прикладной области.

                                                                                        Понимаете ли, весь смысл дискуссии в том, повсеместно ли применим ООП-дизайн. Ну и да, не надо путать «определение объектов прикладной области» и построение модели классов, это совсем не одно и то же.

                                                                                        Пожалуйста объясните фразу «результат проектирования прикладного решения».

                                                                                        А какая часть вам в ней не понятна?

                                                                                        Я имею ввиду фокусирование инженера-программиста на построении модели классов, для него это «ядро» проекта.

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

                                                                                        Простите, Вы здесь о чем?

                                                                                        О том, что в рамках одной системы «ядро» может быть написано, например, на ООП (и императивно), а прикладные решения — декларативно на DSL.
                                                                                          0
                                                                                          Понимаете ли, весь смысл дискуссии в том, повсеместно ли применим ООП-дизайн. Ну и да, не надо путать «определение объектов прикладной области» и построение модели классов, это совсем не одно и то же.

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

                                                                                          Я бы еще раз попросил бы вернуться в тему «ООП», хотелось обсуждать «Как нам это правильно сдеать в ООП», а не то, нужно ли ООП или нет, в определенных случаях.

                                                                                          Мой «message» звучит таким образом:
                                                                                          чаще всего наибольшие трудности возникают при построении модели прикладной области, то, что автор статьи называет «домейнщиной».

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

                                                                                          Пожалуйста объясните фразу «результат проектирования прикладного решения».

                                                                                          А какая часть вам в ней не понятна?

                                                                                          Фразу понял, просто не могу привыкнуть к применяемой Вами терминологии.
                                                                                            +1
                                                                                            Я бы еще раз попросил бы вернуться в тему «ООП», хотелось обсуждать «Как нам это правильно сдеать в ООП», а не то, нужно ли ООП или нет, в определенных случаях.

                                                                                            А зачем? Топик-то не про это.

                                                                                            чаще всего наибольшие трудности возникают при построении модели прикладной области, то, что автор статьи называет «домейнщиной».

                                                                                            … именно потому, что ООП для этого с завидной регулярностью подходит плохо.
                                                                                0
                                                                                Эта проблем решается выделением специальной сущности — «менеджера». В результате у объекта типа «банковский счёт» не остаётся метода перевести_на(счёт, сумма), а вместо этого у объекта типа «менеджер счетов» появляется метод перевести_с_на(с_счёт, на_счёт, сумма).


                                                                                Вы говорте о том, что мы приходим к тому, что «Domain objects» лишаются методов и все, что касается их поведения передается объектам-менеджерам. Это удобно с точки зрения дизайна ПО, но это «ломает» концепцию моделирования кусочка реального мира с помощью ООП(полагаю это основная причина его создания), так как бизнес-логика отделяется от бизнес-объектов.
                                                                                  0
                                                                                  Это удобно с точки зрения дизайна ПО, но это «ломает» концепцию моделирования кусочка реального мира с помощью ООП
                                                                                  Есть выбор. Между «правильностью» и удобством. Менять код менеджера более безопасно, чем менять код доменного объекта.
                                                                                  –1
                                                                                  это не «ответ не знающим», это белиберда! тут чёрт ногу сломит…

                                                                                  Only users with full accounts can post comments. Log in, please.