Pull to refresh

Comments 122

UFO just landed and posted this here
Пост не совсем о боли. Пост для тех, кому больно от того, что должно быть легко и приятно.
Старая байка.Нервы восстанавливаются.

Вы говорите про ООП как отображение реального мира с его объектами. Не могу утверждать, но мне кажется, что вы описали DDD.

SOLID+DDD это и есть реализация идеи ООП. О том и пост, кажется.
Вот вы, коллега, уловили идею
Встречал мнение, которое мне лично очень нравится, что DDD это способ делать ООП правильно.

Да, я согласен с Вами.

Мне кажется использовать лексику типа


… дохера… на хер… гребанная...

в публикации неуместно. Давайте будем хоть немного уважать друг друга.

Правильно, так всех рекламодателей распугать можно.
хотел бы конечно ошибаться, но по моему это автор чуть промазал мимо ebanogo.it но если, только удалят,.там годных статей с ООП чтот маловато.
Не думал, что мне когда-нибудь доведётся это написать, но:
Гиперссылки не склоняются
Отлично, новое правило современного языка :)
UFO just landed and posted this here
Ты и правда думаешь, что чтобы писать статью про то что ООП не работает — надо постараться и докопаться до истоков, изучить OOP в смолтолке, посмотреть хотябы пару не мейнстримных реализаций типа CLOS, IO? Разве стоит изучить серьезные научные работы на эту тему, типа https://www-master.ufr-info-p6.jussieu.fr/2006/Ajouts/Master_esj_2006_2007/IMG/pdf/Coin87.pdf? Нет, хабр и так сожрет.
UFO just landed and posted this here
Ещё я очень полюбил брейнфак, как язык с абсолютно нестандартным подходом, отлично подходит на собесы


А еще это идиотизм
Ну и вобще, автор еще зелен такие тексты писать. Если уж собрался критиковать ООП так хоть подойди с толком и грамотно. Например, так: https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53#.9iei73aa9
По ссылке эталонный пример неосилятора ООП типа «мне сказали что будет хорошо, а оказалось что надо думать головой». В текущей же статье, несмотря на отвратительный стиль изложения, мысли в целом верные.
Погоди, а в чем неосиляторство? Первый пример у него — хотел отнаследоваться от чужого класса, оказалось что надо тащить за собой его родителей, и соседние классы, что тут неосилено? Второй — кто-то изменил код класса в иерархии из-за чего поломался его собственный код. Не осилил создать собственную копию иерархии или что? Дальше про то, что конструктор клонирует объекты для инкапсуляции, а клонирование в общем случае невозможно — тоже его неосилятороство?
Да. Ибо это неверное использование инструмента.

Первый пример имеет смысл только если он захотел перенести часть классов в другой проект, иначе за всё отвечает компилятор\линкёр, и мне интересно посмотреть на код кейса, потому как в нём явно какой-то косяк. А если ты переносишь часть кода между проектами — тут уж прости.

Второй пример вообще не относится к ООП, у вас точно так же всё порушится в хаскеле, если кто-то внезапно решит «поправить» какую-нибудь библеотеку.

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

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

В общем, да, это неосиляторство.
>А если ты переносишь часть кода между проектами — тут уж прости.

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

>Второй пример вообще не относится к ООП, у вас точно так же всё порушится в хаскеле, если кто-то внезапно решит «поправить» какую-нибудь библеотеку.

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

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

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

>так как ссылки появились ещё при царе горохе, а move-семантика существует больше 5 лет.

Про move-семантику не знаю, честно, но как ссылки помогут в этом примере?
> оказалось что отнаследоваться не может не скопировав определенную часть иерархии.
Попробуйте собрать тот же DeepArt или Chromium, не скопировав все зависимости. А я на вас посмотрю.

> не может повлиять на вызвавший код никак, кроме как возвращаемым значением
А больше и не надо. Делайте функцию, которая возвращает структуру (кортеж или как он там будет обзываться), в одном из обновлений поменяйте порядок полей в структуре, и вуаля! Все пользователи вашей библиотеки, которые не пересоберут свои бинарики под новую семантику, начнут активно жопожечь всё вокруг. Причём тут ООП, если это бинарно совместимое изменение API, меняющее логику приложения? Это не проблема инструмента, это проблема проектирования.

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

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

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

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

В свою очередь, современным крупнейшим системам становится недостаточно и трех измерений, так рождается dependency injection, модульность, настройки компилятора c++ и т.д.
Что интересно, это вовсе не вопрос синтаксиса, а значит lisp-подобный язык в итоге позволил бы создавать ПО любой мерности. Боюсь только, человеческий мозг с таким уже не справится.
> Интерфейс требует у объекта наличие поведения для внешнего взаимодействия
> interface Knob
>{
> public function take(Holder $with);
>}
>
>class Cup extends Vessel implements Knob
>{
> public function take(Holder $with)
> {
> //Как-то мы можем держать стакан держателем
> }
>}
Пример порадовал. Кружка не должна браться. И ручка не должна. Мы же в быту не оперируем понятиями «кружка взялась моей рукою», не так ли? Кружка, как и ручка, должна иметь физические параметры. Брать — работа держальника, и уже он по физическим параметрам должен определять, возьмётся кружка или нет. Точнее даже не он, а deus, подсчитывающий физику, но deus, как известно, ex machina, потому пропустим его существование. Чтобы было понятнее, кружка должна наследоваться от, к примеру ExtandedPhysicalObject, который хранит физические параметры, и в его глубине должен быть желанный флаг FeaturesForDisabled::HookConnector4Inch, который чётко укажет, что 4-х дюймовым крюком объект можно взять. Важно, что объект может только производить действия, он не может действоваться другим объектом.

В других случаях я бы не стал так расписывать, но вы сами написали
> в первую очередь вам нужно понимать принципы работы каждого инструмента для того, чтобы наиболее эффективно и правильно использовать его.
Получайте свой
> приятный толчок в свою <...> квалификацию
На самом деле, кружка не реализует интерфейс.
Человеки привыкли брать кружки, но не умеют это делать по умолчанию.
А это значит, что взять кружку — навык, а не способность. У человека почти всё навыки, ибо этому учится.

Человек учится хватать всё подряд. Но это же не значит, что у всего, за что я ухватился есть интерфейс — хватабельный?
Это всего лишь значит, что всё, у чего допустимый для подъема вес, может быть схвачено человеком.
Такие вещи не очень приятно запихивать в код в любой форме, поэтому интерфейсы — меньшее зло, вполне допустимое в качестве примера в статье в том числе.
> А это значит, что взять кружку — навык, а не способность. У человека почти всё навыки, ибо этому учится.
> > Кружка, как и ручка, должна иметь физические параметры. Брать — работа держальника, и уже он по физическим параметрам должен определять, возьмётся кружка или нет.
Где противоречие?

Вопрос был не о необходимости интерфейсов, а об их корректности. Не кружка должна проверять, может ли она быть взята рукой. Не кружка должна реализовывать хват. Максимум, что она может обеспечить — свою форму, то есть иметь различные крепления, и, значит, она может быть только параметром take, а не инициатором.
Это вопрос реализации.

Может ли кто-то кроме человека взять кружку? Может.
Со стороны реального мира нет явной связи субъект-объект, любое живое существо может что-то взять так или иначе.

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

Да, пример в статье оторван от реальности, но он таки реализует какую то логику с какой то целью, вы не можете однозначно утверждать, что это неправильная реализация. Реализация зависит от цели.
И снова мимо. Речь не о том, кто может хватать кого за что. Дело в том, как мы это описываем. И я в примере придираюсь к конкретной форме описания «кружка берётся». Кружка не может «взяться», она может «быть взята». Потому у неё не должно быть интерфейса аля take() или takeable(). У неё должны быть size(), mass(), который учитывает массу хранимой жидкости, и, видимо, specialHolders(), указывающие на наличие анатомических особенностей от ручек до прорезей и usb-разъёмов. А уже хватальник должен проверять, сможет ли он эту штуку взять или нет.
Если разработка идёт по о кружках, то интерфейсы вида «Кружка берется» обычно оказываются удобнее, чем какие то свойства размер\вес\форма по которым кто-то сам будет разбираться, сможет ли взять.

Разработка тем и отличается от реального мира, что идёт для конкретных целей. Делается людьми и для людей, а не для полного соответствия реальности =)
Вот после таких вот допущений людят уходят в мона… кхым… в функциональное программирование.

Если в приложении предусмотрена возможность брать, то «take» — это метод берущего. Если в приложении можно писать, то 'write' — метод пишущего. То есть конкретно в энтерпрайзе делается object::serialize и file::write, не допускается object::writeToFile, кроме редких частных случаев. Иначе теряются рамки ответственности, и в конкретные моменты возникает сильная связность между логически разнородными объектами, которая не решается в рамках выработанных интерфейсов.

Вот, например, допустим, есть Holder::Hand и Holder::Hook, и для них у стакана и кружки разное поведение Cup::take(holder). И в определённый момент открытия в робототехнике и японской анимации позволяют получить holder::tentacle. Нам, получается, нужно добавить новый код проверки в каждый тип кружек? А потом выяснилось, что некоторые заказчики хотят кружки с 3 ручками, мы вынесли ручки в отдельные классы, которые агрегируются у кружек, после чего появляется неразбериха, кто должен проверять, что можно взять кружку: кружка или ручки? И в каком порядке? Потом начинается учёт температуры продукта, после чего получается, что если у бокала есть ручка, то можно брать горячий бокал, но только рукой, не тентаклей, а стакан можно брать рукой, но только если она в перчатке. Причём, если в кружке кипяток, то можно и тонкую перчатку, а если расплавленное олово, то только в толстой.

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

А потом уже без разницы, как реализован сам метод, если у нас есть спецификация, помогающая определить возможность действия.
И снова нет. Снова мимо. Потому что составление словаря возможных состояний никак не связано с ООП, и оно, как раз, куда ближе к функциональному f(1) => 1; f(2) => 1; f(i) => f(i-1)+f(i-2); ООП — оно про объекты и их взаимодействия.

И нет, разница в том, как реализован метод и к кому он привязан, есть, и огромная. Почитайте комментарий выше ещё раз, если для вас это не очевидно.
Ещё раз, кружка тоже может влиять на то, кто её берет. Встройте в неё систему защиты — бейте током нелегальных пользователей. Процесс обоюдный, а как это реализовывать в коде — зависит только от целей и постановки задачи.
Скажите, как то, что в кружку встроен шокер, влияет на её способность «браться». Не на возможность «быть взятой», а именно «браться»?
Если в кружке есть шокер, значит, интерфейс будет сложнее, нужно добавить метод cup::onStartTakingBy(holder) (или Cup::react(ActionTake,holder), если углублять абстракции), который вызывается из Holder::tryTake(cup). cup::onStartTakingBy пошлёт в holder сообщение electricAttack(1000V,0.01A), а holder уже прервёт выполнение tryTake исключениями ExceptionShock и ExceptionMuchPain. Причём, «пошлёт сообщение» — очень растяжимое понятие, это может быть в прямом смысле сообщение, а может быть циклическое выполнение cup::onStartTakingBy до тех пор, пока она возвращает непустые действия.

При этом, кружка вполне имеет право иметь список соприкасающихся с ней объектов, list<weak_pointer> collisionList, и даже имеет право их токнуть в любой момент времени, если реализует интерфейс шокера. Но «взяться» она по прежнему не способна, ей нечем. Она может «быть взята», и «взять» по прежнему реализует «рука»
Привязались к одному слову, боже мой. Будем считать, что я неправ, а вы правы.
Не нужно мне делать одолжений, прав я или не прав. Я привязался не к слову, а к дырке в логике. Если для вас дырки нет, советую серьёзно задуматься над изучением простейшего логического аппарата и основе декомпозиции систем.

На самом деле, конечно, стоит вспомнить, что методы — это не более, чем синтаксический сахар для диспетчеризации реализации функции по типу первого аргумента. Когда же у вас реализация должна зависеть от нескольких аргументов, то нужна уже множественная диспетчеризация: take( subject , object ). К сожалению, не так много ООП языков её поддерживают. Но некоторые поддерживают и её и UFCS (это когда запись вида subject.take( object ) транслируется в take( subject , object ) с выбором соответствующей реализации)

С этой точки зрения, конечно, всё верно, но есть одно но. UFCS плохо уживается с множественным наследованием и неограниченным ростом иерархий, ведь в какой-то момент в этот код может попасть объект, подходящий под все позиции в вызове. Такая диспетчеризация добавляет не только синтаксического сахара cup.take(holder) /*holder.take(cup)*/, но и жестоких проблем CupWithHand cup; cup.take(holder) /* Hail Skynet! */
Далеко не всегда подобную проблемную ситуацию можно предусмотреть в самом начале или заметить в коде пятилетней давности. Так что запретили такое поведение во многих случаях очень правильно, и без UFCS можно отстрелить себе ногу по самые колокольчики, не нужно делать это с помощью BFG.

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

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

Концепция, конечно, красивая, но если бы мне первому предложили воспользоваться ею, я бы сделал так, чтобы я остался последним.
Пардон, не UFCS, где происходит трансляция a.f(x) => f(a,x), а «множественная диспетчеризация»

"Уже собранные библиотеки" — то ещё зло. Но вообще, не вижу принципиальной невозможности экспортировать внутренние ограничения во внешний контракт.

Меньшее зло, чем jit или интерпритаторы.
> не вижу принципиальной невозможности экспортировать внутренние ограничения во внешний контракт.
В конкретном примере что экспортировать?
Меньшее зло, чем jit или интерпритаторы.

А они тут при чём?


В конкретном примере что экспортировать?

Допустим, у нас есть такая либа:


private auto add( T )( T a , T b )
{
    return a + b;
}

private auto dup( T )( T a )
{
    return add( a , a );
}

public auto quad( T )( T a )
{
    return dup( dup( a ) );
}

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


// должна быть определена операция сложения для типа аргумента
public T quad( T )( T a ) if( is( typeof( a + a ) ) );
> А они тут при чём?
А вы знаете другой способ отказаться от библиотек?
> Допустим
«множественная диспетчеризация» тут причём?
>Компилятор может выводить не только конкретные типы, то и ограничения на них
Перед вами вилка: если выполнять все проверки в рантайме, производительность упадёт на порядки, иначе толку от этих выводов нет.
А вы знаете другой способ отказаться от библиотек?

Конечно:


import my.super.puper.lib;

«множественная диспетчеризация» тут причём?

Это иллюстрация всплытия контрактов из недр библиотеки в публичный интерфейс. Как результат — вы не можете передать ей такой тип, который она не сможет обработать (в том числе и выбрать правильную реализацию).


Перед вами вилка: если выполнять все проверки в рантайме, производительность упадёт на порядки, иначе толку от этих выводов нет.

На этапе компиляции всё проверяется.

> import my.super.puper.lib;
Это?.. Питоновское включение библиотеки (добавление кодовой базы к интерпритатору)? Или жабье подключение класса (импорт JIT-ассемблера или исходников)? Или макрос, подтягивающий сишный импорт списка функций?
Или это просто красивый способ обозначить отсутствие ответа?

> Это иллюстрация
Не имеет никакого отношения к «множественной диспетчеризации».
Напомню изначальную постановку вопроса:
a.f(b) <-> b.f(a)
Что приводится к виду
f(a,b) <-> f(b,a)
Что допустимо только при выполнении простого требования об отсутствии нескольких параметров одного типа
a1.f(a2,b)
или об асимметричности бесконечномерных отношений. В противном случае придётся накладывать ограничения на порядок следования повторяющихся параметров, что убивает половину удовольствия. Кроме того, механизм наследования прекратит нормально работать, так как в сложных проектах, в которых класс наследует множество интерфейсов, для разрешения конфликтов придётся приводить типы каждого из передаваемых параметров явно, что, согласитесь, ни капельки не сырно.

Это не говоря о том, что подобный синтаксический сахар размывает области ответственности и влечёт за собой очень сложную поддержку библиотек\модулей\хоть-чёрта-лысого, так как на поверхность будут всплывать ограничения компилятора, которые вы никак не сможете контролировать.
Или это просто красивый способ обозначить отсутствие ответа?

Это прямое подключение исходников.


В противном случае придётся накладывать ограничения на порядок следования повторяющихся параметров, что убивает половину удовольствия.

Обычно порядок следования неименованных аргументов важен. В целом я не очень понял о чём вы. Множественная диспетчеризация не вчера придумана и вполне не плохо работает.


синтаксический сахар размывает области ответственности

А вот скажите мне, функция конвертации json в xml — это область ответственности xml или json? А если мне надо добавить конверторы из них в формат tree, то кого патчить нужно?


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

Например?

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

> Множественная диспетчеризация не вчера придумана и вполне не плохо работает.
В функциональных ЯП, где от методов классов, как от основополагающей концепции, отказались. Да и выглядит она далеко не так, как в изначальной постановке задачи.

> это область ответственности xml или json?
Понимаю, к чему вы клоните, но к обсуждаемой теме это не имеет отношения, так как обсуждаются не множественная диспетчеризация в общем, а частный случай трансляции cup.take(holder) в holder.take(cup).

> Например?
Например, получив в первом выпуске ограничения A NOT NULL, вы не сможете добавить A NOT NAN без нарушения API.
В таком случае, изначальный контроль внешних контрактов ложится на человека, а компилятор сможет выступить не более, чем советчиком.
Из этого утверждения следует популистский призыв об отказе от проприетарных приложений, или вы отделаетесь полумерами?

Отказе от неуклюжих попыток спрятать исходники библиотек — да.


В функциональных ЯП, где от методов классов, как от основополагающей концепции, отказались.

В ООП языках она тоже применяется. C++, D, ObjectiveC, Go.


частный случай трансляции cup.take(holder) в holder.take(cup).

Откуда вы взяли эту глупость? take( Cup, Holder ) и take( Holder, Cup ) — разные сигнатуры.


Например, получив в первом выпуске ограничения A NOT NULL, вы не сможете добавить A NOT NAN без нарушения API.

Я не смогу изменить апи без изменения апи?

> Отказе от неуклюжих попыток спрятать исходники библиотек — да.
Удачи.

> Откуда вы взяли эту глупость? take( Cup, Holder ) и take( Holder, Cup ) — разные сигнатуры.
Давайте сначала. Я указал автору на то, что декомпозиция предметной области в текущей постановке некорректна. В частности, что cup.take(holder) приводит к неверным ассоциациям. Вы влезли в защиту MonkAlex со своей множественной диспетчеризацией и отходом от методов к функциям. Я много раз у вас переспрашивал, мол, если множественная диспетчеризация не про взаимозаменяемые сигнатуры, то нам с вами не о чем спорить, а вы настаивали на своём. Зачем? Что вы имели в виду? Пёс знает. А теперь вы мне это ещё и в вину ставите. Ну нет, это вы читаете собеседника через 2 строки.

> Я не смогу изменить апи без изменения апи?
Вы сами написали
>> Компилятор может выводить не только конкретные типы, то и ограничения на них, в результате чего у либы получается такой публичный интерфейс
Компилятор. Без участия человека. Да, ВЫ не сможете сменить АПИ или обеспечить обратную совместимость. Либо так, либо ваша концепция должна не хило так измениться.

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

ООП так не работает. В ООП у каждого сообщения есть инициатор, он же — субъект взаимодействия и владелец метода в одной из реализаций. Вам не нравится? Добро пожаловать в «секту неосиляторов» или в «функциональный клуб», как вам будет приятнее.

Ну, вам, наверно, виднее как ООП работает, а как — нет.


class Cup
{
    float radius = 3;
}
class Fork {}
class Spoon {}

class Hand {}
class Hook
{
    float radius = 4;
}
class Tentacle {}

void take( Object )( Hand subj , Object obj )
{
    writeln( typeid(subj) , " take the " , typeid(obj) );
}

void take( Object )( Tentacle subj , Object obj )
{
    writeln( typeid(subj) , " take the " , typeid(obj) );
}

void take( Hook subj , Cup obj )
{
    enforce( subj.radius == obj.radius , "Hook and cup must be the same radius" );
    writeln( typeid(subj) , " take the " , typeid(obj) );
}

void main()
{
    ( new Hand ).take( new Spoon );
    ( new Hook ).take( new Cup ); // Runtime exception: Hook and cup must be the same radius
    ( new Hook ).take( new Fork ); // Compile Error: None of the overloads of 'take' are callable using argument types (Hook, Fork)
}
> Ну, вам, наверно, виднее как ООП работает, а как — нет.
Читайте внимательнее
>> и владелец метода в одной из реализаций
Я не спорю в форме выражения мысли. Языки могут быть разными: lisp, java, c++, английский, русский, китайский и многие многие другие. Я, по непониманию сути вашего первого комментария (на тот момент я действительно подумал, что вы сетуете за эквивалентность разных сигнатур) с вами поспорил, но, когда до меня дошло, я сразу вам написал, что нам с вами спорить не о чем, это манера речи, не более.

Если на этом наше непонимание исчерпано, предлагаю завершить.
Больше меня порадовало, что после этого примера идёт фраза:

«Этот пример не очень аккуратный и продуманный, зато полностью передает то, как из концепции ООП вытекает всё то, что так требуют на собеседованиях. Именно это понимание и позволяет следовать SOLID принципам».

Хотя пример нарушает принцип единственной обязанности (SRP, который в SOLID первый, т.е. S).
Извините, но толчок не получился. Вы слишком категорично настаиваете на своем видении ООП как единственно верном, в то время как он не то что не единственное, так еще и рассматривается иногда как не очень верное. Я прекрасно понимаю откуда растут ноги, все книжки про ООП начинаются с того, что рассказывают про мышление человека на основе объектов, показывают, что мир вокруг нас состоит из объектов и заканчиваются тем что показывают, как эти объекты представить в коде. При этом, если автор не предложит моделировать окружающий мир 1:1, то читатель сам сделает такой вывод в 100% случаев. Яркий представитель такого подхода в ООП Ivar Jacobson. Это очень понятный и удобный подход (по сути это готовый фреймворк для декомпозиции, как видишь мир так и дели его на классы), но у него есть недостатки и некоторые считают их фатальными. Могу выделить одну проблему о которую этот способ декомпозиции сильно спотыкается. Мир состоит из двух типов объектов — очень умных(человек) и абсолютно тупых(кружка). Если вы будете переносить, то что видите в реальности в код 1:1, то в результате вы получите жирнющие контроллеры (god object) манипулирующие тупыми объектами. Фаулер даже анти-паттерн такой описал Anemic domain model, утверждая, что это процедурный дизайн, а не объектный. Поэтому, нельзя утверждать на основе предложенного контекста, должна кружка браться или нет.
Вы вкладываете в мои уста чужие слова и начинаете с ними жарко спорить. При этом не видите очевидных прорех. Чем больше я получаю подобных комментариев, тем сильнее убеждаюсь в том, что мне имеет смысл попробовать себя в проектировщиках.

>то в результате вы получите жирнющие контроллеры (god object) манипулирующие тупыми объектами
>> Точнее даже не он, а deus, подсчитывающий физику, но deus, как известно, ex machina, потому пропустим его существование.
Именно этой фразой я отсёк чрезмерную декомпозицию. Заметьте, я не протестовал против cup.fill или против cup.takeSome, так как это логичное поведение контейнера. Если логичным поведением абсолютно тупого объекта будет вызов какого-либо события, я так же не скажу ни слова. К примеру, если конкретная реализация не должна учитывать тип жидкости, считая её по умолчанию водой, присобачивание таймера на испарение я поддержу обеими руками, а если жидкости будут разными, то за внесение dt для таймера в её недра.

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

Если короче, ООП должно идти в обнимку с SOLID и DDD. Как и ФЯП должны идти в обнимку с мат. выкладками, а xml/json — с валидными схемками.
Вообще, не обязательно пытаться кольнуть собеседника, чтобы после этого высказать свою точку зрения.
Я говорил о том, что способ точного отображения реального мира в декомпозиции имеет свои недостатки и написал какие. Но также есть другие подходы к декомпозиции, в которых объекты наделяются поведением которым оно не свойственно, нравится вам это или нет. Я не очень понял что такое чрезмерная декомпозиция, и с чем конкретно вы не согласны.
Не обязательно драться с ветряными мельницами, но вот ваш комментарий, а выше моя ветка с vintage'ом, и вот все трое из нас сидят на привале, и вокруг каждого из нас бегает свой Санчо.

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

Так вот, я не могу придумать ситуации, когда item должен в такой мере управлять собственным control'ом. Я не могу придумать такой ситуации, когда чашка должна обеспечивать и контролировать желание руки её взять.
MonkAlex предлагал вполне не сферическую ситуацию, когда кружка бьет током, более того, аналогичную ситуацию разбирал Peter Coad в какой то из своих книг. Но вы всех нас обвиняете в неправильном подходе к дизайну. Может вам все-таки стоит взглянуть на вещи шире?
Согласитесь, что этот пример вынут из известного места, и я уже описал узкие места такого дизайна, так что повторяться не вижу смысла, что до Пети, мне не попадалось его книг. ничего не имею сказать.
И, если что, я привёл пример, при котором кружка может иметь свою руку. В этом случае интерфейс становится, мягко говоря, неоднозначным, что явно свидетельствует против него.

Я, вообще, не против взглянуть на вещи шире. Но, как в старой шутке, любоваться мозгом — это избыточный подход.
Не могу согласиться, в моей религии это нормально. Только совсем не то что вы написали про контроль над желаниями другого объекта и управлением собственным контролом. Контроль это больше про структурное программирование, в ооп объекты пересылают друг другу сообщения. Попробуете взглянуть на ситуацию под другим углом, исключите контроль и ограничьте дизайн сообщениями. В системе где объект рука посылает сообщение объекту кружка, никакие другие объекты окажутся не нужны, а проверка права посылать сообщения кружке естественным образом окажется делегированной самой кружке.
> В системе где объект рука посылает сообщение объекту кружка
Нет никаких проблем. Но ведь я придрался к системе, в которых КРУЖКА посылает сообщение РУКЕ, выступая инициатором. Не отвечает на сообщение, а именно инициирует. Почитайте пример в очередной раз, в очередной раз перечитайте все эти тупые деревья комментариев.
Кто в этом листинге посылает кому сообщение? Кто выступает инициатором?
В том что я привел, инициатор не указан, а получатель сообщения очевидно cup. Но если предполагается отправка сообщения от руки кружке, то эта строка должна вызываться внутри одного из методов руки в виде cup.take(this). Как то так.
ООП отличается тем, что достаточно просто транслируется в естественный язык.
«cup.take(holder)»
«cup take holder»
«Кружка возьми\берёт\взять держатель»
Пожалуйста, ответьте мне, где с точки зрения естественного языка подлежащее, сказуемое, дополнения и тп. Ответьте, насколько с точки зрения естественного языка грамотно это предложение.
Ну это как сказать, я например, уверен что, несмотря на рассказы про естественность объектов для мышления, функциональная декомпозиция гораздо проще и понятней объектной. И можно даже построить цепочку методов которая будет 1 в 1 как предложение на естественном языке. Что касается вопроса, то это несоответствие имеет место быть, но это такой момент к которому легко привыкнуть и проблем это вызывать не должно.
У вас же наверняка есть пример, по которому можно составить сравнение декомпозиций в плане понятности? Без примера — голословно.
Готового примера нет, есть общие соображения. Функциональную декомпозицию в состоянии выполнить любой человек обладающий алгоритмическим мышлением, в то время как объектная требует определенных навыков. Тут например http://www.wirfs-brock.com/PDFs/How%20Designs%20Differ.pdf автор сравнивает свое видение мира с тем, которое на мой взгляд, получило наибольшее распространение. Централизованный контроль проще понять, но Wirfs-Brock выступает за децентрализацию контроля, а потом проходит 10 лет и появляется вот это https://en.wikipedia.org/wiki/Data,_context_and_interaction где говориться, что взаимодействие объектов нельзя децентрализовывать. Короче, все сложно.
Готового примера нет, есть общие соображения.
Пруфов нет, но вы держитесь!
Функциональную декомпозицию в состоянии выполнить любой человек обладающий алгоритмическим мышлением, в то время как объектная требует определенных навыков.
https://habrahabr.ru/post/251089/
Wirfs-Brock выступает за децентрализацию контроля
В ООП мы описываем предметную область — большой сложный объект. Соответственно, всё, что в неё включено, является полями главного объекта, а связи — определяются методами главного объекта.
Это нам говорит системный анализ.
Если вы потрудитесь походить по моим ссылкам, то обнаружите что «Wirfs-Brock выступает за децентрализацию контроля» а Trygve Reenskaug и James O. Coplien утверждают что децентрализованное управление менее понятно. Я понимаю, что эти люди не для всех являются авторитетами, но кроме этого я могу только ссылаться на здравый смысл, который должен подсказывать, что централизованный контроль должен быть проще для понимания чем децентрализованный. Это ваше дело, считать это пруфами или нет, но других я предложить не могу.
Я не понял что доказывает ваша ссылка.
В ООП мы описываем предметную область — большой сложный объект. Соответственно, всё, что в неё включено, является полями главного объекта, а связи — определяются методами главного объекта.
Это нам говорит системный анализ.

Я не знаком с такой системой декомпозиции, но могу представить это монструозное творение, когда вся предметная область находиться в одном объекте.
Не могу ничего сказать про системный анализ. меня это область мало интересует, но если системный анализ предписывает делать именно то что вы говорите, то опасаюсь, что это сугубо академическая область против которой прямо и косвенно предостерегают David West и Eric Evans соответственно.
Оффтоп
Слава яйкам, я снова могу в теги!
Вы немного замкнулись. Взгляните на мир шире!

Что есть объект? Совокупность его составных частей и связей между ними. Иначе говоря, система. Что такое декомпозиция? Выявление этих частей и связей. Что такое управление? Некоторый объект, на состояние которого мы можем влиять непосредственно, и который распределяет это влияние далее по системе. Что такое децентрализованное управление? Наличие нескольких таких объектов. Они все будут являться частью системы, так как они связаны с остальными объектами системы. Нужно продолжать рассуждение, или на этом этапе уже ясно, что децентрализация — это просто деградация ООП, так как изначальная концепция не ставит ограничений на количество, качество, порядок и приоритет управленческих объектов и связей.
могу представить это монструозное творение, когда вся предметная область находиться в одном объекте.
Лол.
Ужаснитесь:
Точка входа — максимально широкий объект в рамках приложения.
public class MyApplication {
    public static void main(String[] args) { } // Java
}
class MyApplication : public QApplication {
    int exec() { return 0;} // C++ Qt
}

int main(...){
MyApplication app;
return app.exec();
}

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

И, да, не забывайте
Мы отошли от обсуждения плохого дизайна.
Да что там советские ученые, элементы системного анализа были известны уже в Древней Греции :)
И даже до них, древние египтяне зря папирус не тратили. Но, всё-таки, фору Эвансу или Вирту они дать не могли, будем честными.
Эвансу или Вирту вряд ли, а нынешним двадцатилетним senior-ам — запросто. :)
Я как то не уловил связи между определением объекта и выводом о деградации.
Я ожидал увидеть объект «вселенная» и 100500 его полей, или имелось в виду что то другое?
Ваше мнение о важности системного анализа и невозможности полноценной разработки без него, на чем то еще основывается кроме вашего мнения? И еще интересно, в свете вашего увлечения формализацией, что вы думаете про аджайл?
Я как то не уловил связи между определением объекта и выводом о деградации.
Нужно продолжать…
Ну так вот, ООП не накладывает ограничений ни на объекты-контроллеры, ни на способы передачи сообщений (хоть телефонистку садите). Единственное ограничение — они должны иметь связи, то есть составлять единую систему. Вы же, устами авторитетов, пишите о том, что не должно быть единой системы, должно быть разделение зон влияния, децентрализация, которая разделит систему. Но, если нет единой системы, значит есть несколько меньших автономных систем, которые вы пытаетесь сшить как монстра Франкенштейна в одном приложении. Действительно, если есть несколько небольших систем, зачем их пихать вместе, реализуйте их отдельными приложениями. Но тогда у вас снова получаются централизованные объекты, пусть и меньших размеров. И вы попадаете в циклический гаплык. Или так, или вы используете неверную аргументацию. Я по-диагонали прочёл первые 70 страниц Вестовского Object Thinking, и там такой херни не было, ум за разум у старика не уходит. Да, у него проскальзывает, что не нужно делать бога в приложении, но ничего такого, что противоречит ООП у него нет. По крайней мере, в той части, которую я прочёл.
Я ожидал увидеть объект «вселенная» и 100500 его полей
Извините, вселенная — это проприетарная разработка, и я, в силу установленных нанимателем ограничений, не могу выложить исходный код.
или имелось в виду что то другое?
Имелось в виду, что вы если и кодите, то бездумно. С таким подходом спагетти-код — самое лучшее, чего стоит от вас ожидать.
Ваше мнение о важности системного анализа и невозможности полноценной разработки без него, на чем то еще основывается кроме вашего мнения?
На том, что это университетская дисциплина? На том, что ею активно занимаются как в нашем РАН, так и в Бостонском и Массачусетском университетах? На том, что она систематизирует эмпирические знания, полученные от танцев на граблях с бубнами многих групп, реализовывавших монструозные проекты?
Да не, это Вася Пупкин захотел сказать, что её надо знать. Уж кто-кто, а Вася-то знает, что говорит.
И еще интересно, в свете вашего увлечения формализацией, что вы думаете про аджайл?
Ничего. Ajile не противоречит ни одному из утверждений. Если думаете иначе, приводите конкретные примеры. А пока получается, что вы просто боитесь признать свою неправоту или неграмотность, так как не привели ни одного интересного аргумента или острого вопроса, которым можно было бы меня пырнуть.
Я честно пытался понят ваш ход мыслей, но у меня не получилось, ваш логический вывод для меня не очень логичен, авторитетных источников описывающих вашу картину мира вы не приводите. То что в университетах что то изучают, еще не является доказательством того что это применимо на практике, аджайл как раз является подтверждением того что индустрия отказалась от тяжелых формальных методологий. То что мои источники противоречат вашему мнению вы не видите. Я не вижу смысла продолжать этот диалог.
Если вы все-таки можете привести какие то источники передающие вашу картину мира, буду рад ознакомиться.
И ваше последнее предложение больше относиться к вам, чем ко мне, ни я ни вы не находимся на уровне авторитетного мнения, но постоянно требуя от меня доказательств, которые я, кстати, старался приводить, вы почему то решили что вашего мнения достаточно, Не достаточно. А если учесть тон последнего предложения, на ум приходит только одно «Юпитер, ты сердишься — значит, ты не прав»
Системный анализ — это методология, такая же, как наблюдение и эксперимент. А ajile, как и waterfall — модель подхода к процессу разработки. Не методология. Ничто не мешает подходить к системному анализу небольшими итерациями, как завещает ajile, выделяя на первых этапах небольшую часть объектов и тут же реализуя их в коде.
А то, что вы плюётесь, показывает, что вы даже не удосужились прочитать, что же такое «системный анализ», за что он стоит и как работает. Аккуратнее нужно быть.
авторитетных источников описывающих вашу картину мира вы не приводите
Я оперирую только классическим определением терминов «система» и «объектно-ориентированное проектирование», с которыми вы можете ознакомиться самостоятельно. Я ни разу не вышел за их рамки. Какие я должен привести доказательства, если я просто жонглирую самыми базовыми понятиями?
«Юпитер, ты сердишься — значит, ты не прав»
Я расстроен. Это не злость, это грусть разочарования. Вы мне пытаетесь противоречить, но делаете это в тех местах, в которых противоречия нет. А те места, в которых оно есть и на которые я вас навожу, вы избегаете. Это просто печально.
Я прочитал статью в википедии, мне достаточно того что это еще одна формальная методология. Я не понимаю как можно было не заметить что West отрицает формальные методологии. Это все хорошо в теории, на практике я ни разу ничего подобного не видел. Но может быть вы мне ткнете пальцем где написано что какие то известные компании используют эту методологию? Ну не возможно, чтобы все это использовали и при этом нигде ничего об этом написано не было.
Это ваше мнение про «базовость» я с ним не согласен, нужна ссылка.
Давайте без «наводок», прямой вопрос, прямой ответ. Но потрудитесь привести источники.
Вам свойственно делать сомнительные логические заключения, и обвинять собеседников в безграмотности.
При этом на вопрос о классе со 100500 полями вы зачем-то приводите какую-то ерунду, на на уточняющий вопрос ссылаетесь на NDA. Это совершенно не конструктивное поведение. Не знаете как выйти из диалога? Продолжайте в той же манере и я просто перестану вам отвечать.
Я не понимаю как можно было не заметить что West отрицает формальные методологии

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

https://ru.wikipedia.org/wiki/Система
https://ru.wikipedia.org/wiki/Объектно-ориентированное_программирование
Если найдёте, где я вышел за рамки определений и основных понятий, зовите.
При этом на вопрос о классе со 100500 полями вы зачем-то приводите какую-то ерунду
100500 полей? Просто контейнер элементарных частиц и метод calculatePhysics. Что считать элементарным — другой вопрос, относящийся уже к проектируемой модели.
Ключевое слово здесь «формальный», если кто-то что-то использует не осознавая этого, то это что-то уже не может называться формальным.
Я не вижу чтобы наш диалог куда-то двигался, поэтому я решил его завершить.
Ясно дело, вам нечем возразит и нечем упрекнуть, потому, с вашей точки зрения, диалог простаивает. Хотя упрекнуть можно было хотя бы тем, что https://ru.wikipedia.org/wiki/Формальные_методы != методологии научного познания, а, значит, половина моей аргументации летит в трубу. В свете этого нового знания выступление Веста играет новыми красками. Однако это же новое знание полностью выбивает фундамент вашего возражения, так как из необходимости построения модели не следует необходимость обоснования её математической непротиворечивости и достоверности.
Я вообще то вот с этим был не согласен «А системный анализ стоит изучить, если вы желаете быть чем-то большим, нежели просто кодобезьянка.» и как я уже говорил, это опровергается практически. Тот факт что вам надо искать, что кто то это использует уже говорит о том что утверждение не верно. Индустрия живет и развивается не заморачиваясь формальными методологиями. Основная тема Веста это то, что научное сообщество уже 4 десятка лет пытается разработать подходы к упорядочиванию процесса разработки, чтобы сделать его более предсказуемым и контролируемым, но пока результата нет. Это творческая деятельность и приравнивание ее к строительству некорректно. Кстати, аджайл это не тоже самое что итеративная разработка. То что вы привели ссылки на википедию, не делает ваши логические выводы про деградацию верными. Я плохо понимаю логическую цепь ваших рассуждений, может быть по этому прогресс для меня не очевиден. А крючкотворство мне мало интересно.
А вы не находите, что сознательное применение инструмента существенно отличается от случайного? То, что об использовании системного анализа никто не говорит — не означает, что использование не имеет места. Особенно в свете того, что таким вещам, как декомпозиция и стратификация обучают на младших курсах практически во всех технических университетах, не особо упоминая об их отношении к системному анализу, а иногда и не упоминая сами названия методов.
Я согласен с тем что вы говорите, и никогда против этого не возражал. Лучше больше знать чем меньше. Суть моего поста в другом, можно успешно разрабатывать без использования формализованных подходов. А одно лишь использование формализованных подходов не дает гарантии успеха. Короче «А системный анализ стоит изучить, если вы желаете быть чем-то большим, нежели просто кодобезьянка.» это заблуждение.
То что вы говорите про образование, это совсем не однозначно. У нас сильная фундаментальная наука, но то что связано с проектированием софта, лично мне сильно не нравится.
Я вообще то вот с этим был не согласен
Мало ли, с чем ты не согласен. Можешь несоглашаться ещё и с математической статистикой, это тоже чисто формальная методология.
Тот факт что вам надо искать, что кто то это использует
Он говорит о том, что я не знаю всего. Мне и Веста гуглить пришлось, и плюсовый стандарт приходится периодически. И что, это означает, что они опровергаются практически?
Индустрия живет и развивается не заморачиваясь формальными методологиями.
Человечество больше 8000 лет жило до появления зачатков формализованного подхода и научного познания. «Раньше было лучше»?
пока результата нет
Скажите, а как много людей хотя бы знает те самые процессы, не говоря о следовании им? Промилле?
Это творческая деятельность и приравнивание ее к строительству некорректно.
Это инжинерия. Почитайте про успехи формализации других инжинерных направлений.
Кстати, аджайл это не тоже самое что итеративная разработка.
Согласен, это итеративная разработка в условии отсутствия вменяемого технического задания и понимания предметной области. Это не предъява, а констотация фактов. Но это не делает из аги серебрянной пули.
То что вы привели ссылки на википедию, не делает ваши логические выводы про деградацию верными
А вы перечитайте, с какой целью я их привёл. С той целью, чтобы показать, что я не вышел за рамки определений в своих логических па. Если они не верны, ваше право меня в этом уличить. Но вы упускаете другой момент: деградация не всегда отрицательный процесс. Если бы не она, каждый человек был бы метров пять в высоту, был хвостатым, пернатым, покрытым хитином и тп, что, согласитесь, не особо-то и нужно, не говоря уже об удобстве.
Говоря о деградации, мы должны говорить и о специализации. Не всем нужно уметь в полноценную качественную декомпозицию систем высокой сложности. Не всем нужны клыки. Но иметь хотя бы базовыми навыками системного анализа не помешает, как не помешает умения счёта, чтения, логического мышления.

Вы выставляете меня каким-то троллем, желающим над вами поиздеваться. Отчасти это верно, но, в основном, я пишу о том, что для того, чтобы заниматься построением сложных систем, нужно знать, что ты строишь, для кого ты строишь и какие есть удачные постройки этого же вида. Потому что на одних лишь природных талантах далеко не уедешь.
Ваше последнее высказывание что мне нечего возразить, я опроверг возразив. Опять возвращаемся к логике. Вы используете доводы в которых позднее сами показываете несоответствия, странная позиция. Не в том что показываете, а в том что используете заведомо зная о этих несоответствиях. Для меня смысл диалога понять позицию собеседника поделиться своим мнением или получить какую то новую информацию. Я уже писал что мне не удается понять вашу позицию. А в чем смысл диалога для вас? Умыть собеседника? Но я то в этом участвовать не хочу.
Не надо свое мнение приравнивать к фундаментальным наукам.
И да, Вест говорит что software engeneering не состоялся. Разработка это не инженерия. Это творческая деятельность.
Вы используете доводы в которых позднее сами показываете несоответствия, странная позиция.
Я просто развиваю мысль, которую раньше оставлял нетронутой, не потому, что умышлял, а потому, что действительно об этом не подумал. Такое бывает. Странно, что вы мне не смогли возразить подобным аргументом. Вся ваша позиция сходится к апелляции к авторитетам и заявлениям о неспособности понять мою логику. Не об отсутствии оной или ошибках в рассуждениях. Да, это сейчас был серьёзный укол в ваше самолюбие. Вот второй: вам стоит познакомиться с университетской программой прикладной математики, хотя бы с первыми двумя курсами. Пускай это будет чтение по диагонали, но вы внезапно сможете узнать, что фундаментальная наука серьёзно толкает вперёд всю алгоритмику, а с ней и всю сферу. Я не ставлю под сомнение вашу профпригодность и природные таланты, но ни один гений не заменит системную школу. В космос полетел не энтузиаст, а КБ в несколько тысяч сотрудников.
А в чем смысл диалога для вас? Умыть собеседника?
Видимо, да. Знаете, в интернете кто-то снова не прав...
На самом деле мне интересно понять вашу (и не только вашу) позицию. С самого начала меня интересует ответ на самый первый мой комментарий: как можно прийти к тому, что объект инициирует обмен сообщениями с субъектом? Всё дальнейшее — медвежьи попытки выяснить мотивы.
И да, Вест говорит что software engeneering не состоялся.
Я не спорю. Западный подход к разработке зашёл в тупик. На то есть ряд объективных причин, которые практически невозможно преодолеть, не изменив базовый подход к программированию и, возможно, аппаратную архитектуру.
Разработка это не инженерия. Это творческая деятельность.
Эх, заблуждение. https://ru.wikipedia.org/wiki/Инженерное_дело
Вы не берёте новые программы из неоткуда. Вы используете возможности существующих инструментов. Уже лет 30 как программистам не приходится заново создавать инструментарий, объём стандартной библиотеки и её возможности превращает программирование в конструктор.
У любой нашей системы, кроме вселенной есть внешние объекты, которые не являются частью нашей системы, но с которыми мы можем/должны взаимодействовать. Эти объекты не подчиняются нам напрямую, мы можем лишь косвенно стимулировать (например, API Facebook отвечает только по токену, но токен может быть заблокирован). Мало того, в крупных системах невыгодно централизовывать управление, слишком много накладных расходов. Поэтому жертвуют точностью и гарантированностью результата в пользу объемов. Именно поэтому операционные системы такие ненадежные и уязвимые. Это не хорошо и не плохо, но это показывает, что в реальном мире выгоднее всего действовать так. Мало того, наш мозг чаще свего действует не по строгой инструкции, а накапливает ошибки и ставит заплатки.
А программирование — есть процесс переноса мыслей, путем приблизительных слов, компьютеру. А это означает, что если мы сможем описывать задачи сразу со 100% управлением всеми ресурсами, то нам не понадобится программирование — компьютер и так будет все понимать.
Наше приложение и facebook образуют единую систему, но они обособлены друг от друга. Для отображения поведения facebook у вас есть локальный класс, реализующий хранение данных с сервера и подмножество API. Именно этот класс и будет классом управления, он будет составной частью вашей подсистемы и будет существовать в ней вне зависимости от доступности серверов facebook.
ООП не противоречит разнесению системы на несколько приложений, не противоречит передачи сообщений через сокеты в виде json.
ООП не запрещает использовать ленивые или распределённые механизмы, это всё вообще никак не пересекается с ООП.

Вы мне пытаетесь доказать, что ООП противоречит децентрализации, но не показываете, чем именно.

А это означает, что если мы сможем описывать задачи сразу со 100% управлением всеми ресурсами, то нам не понадобится программирование — компьютер и так будет все понимать.
Поясните, мне просто непонятны взаимосвязь доступности ресурсов и компьютерной логики.
Например, вы наняли дюжину детей Азии на стройку. У вас есть ресурсы, есть схемы и наглядные материалы, но как это поможет объяснить этим самым детям, чего вы от них хотите?
Я пытался доказался, не то что ООП противоречит децентрализации, а то что не подразумевает ее. И нет никакой единой системы, это иллюзия. Класс есть, но гарантий нет. Facebook может поменять поведение, а класс останется тем же самым и система просто перестанет работать. А в рамках замкнутой системы такое невозможно.
Так что либо вы говорите о системе «Вся вселенная», либо о децентрализованной и нет (да и не нужно) никакого глобального (стартового) объекта.

> У вас есть ресурсы, есть схемы и наглядные материалы, но как это поможет объяснить этим самым детям, чего вы от них хотите?
Никак, потому что система не централизованная, а дети не являются частью этой системы. Это внешние объекты, с которыми разные наши объекты могут независимо общаться.
Вы, похоже, не понимаете, в чём суть работы программиста. Программист описывает модель системы в терминах компьютерного языка для последующего её выполнения. Ключевое слово — модель. Модель — некоторое отображение реальной системы, она может быть неточной, неактуальной, ошибочной. ООП, как и СП, ФП и прочие МП, никак не отвечают за модель, это не их уровень, они определяют термины описания модели. Модель определяется на этапе проектирования и, очень часто, описывается на UML под все типы ЯП сразу.

Facebook и ваше приложение — два объекта. Между ними есть связь — авторизация по токену. Согласно простой логике они образуют систему. Система — это новый объект. Новый объект может стать частью ещё более сложной системы, если, например, ваше приложение будут дёргать из командной строки или AutoIt. Если часть системы изменится, остальная будет вынуждена либо приспособиться, изменив свою часть модели, либо умереть, пытаясь.
Я сейчас пишу очень банальные вещи, но что поделать?

Так вот, что в ваших терминах децентрализация? Децентрализация — это, как раз, наличие нескольких автономных объектов в системе, зависимость которых от вас стремится к нулю. Например, facebook переживёт, если вашего приложения не будет, обратное, в общем, не верно. Аналогично и с пользователем, и с ОС, на которой производится запуск. Что это в терминах ООП? Это объекты, доступ к которым производится через некоторые прокси-классы. Тот же File — прокси-класс для доступа к файловой системе. В терминах ООП нет децентрализации, так как нет и централизации. А, значит, поднятая вами проблема не относится к ООП, а находится этажом выше, в проектировании приложения — построении модели системы.

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

А я бы нанял прораба-переводчика, который бы на их родном и русском матерном быстро бы наладил процесс производства. Они являются частью системы, просто для взаимодействия с ними нужно выполнять некоторое преобразование данных. Написать соответствующий прокси-класс.
Вы уж определитесь, можно ли с помощью ООП описать всю систему? Хотя, вы уже признали, что нельзя. Так вот теперь подумайте, с помощью чего вы подниметесь на этаж выше и опишите модель системы.
>А я бы нанял прораба-переводчика, который бы на их родном и русском матерном быстро бы наладил процесс производства. Они являются частью системы, просто для взаимодействия с ними нужно выполнять некоторое преобразование данных. Написать соответствующий прокси-класс.
И правда, чож тысячи книг по управлению проектами пишутся, а сотни стартапов закрываются из-за неэффективного менеджмента, всего-то нужно нанять прорабов-переводчиков)
Вы уж определитесь, можно ли с помощью ООП описать всю систему?
Реализовать модель системы — да, можно. А, значит, описать — тоже. Только вы не путайтесь. Выбор ООП как терминологии выходит из составленной модели, а не наоборот. Кроме того, я не писал, что ООП — это самый полный и удобный способ описания модели.

И правда, чож тысячи книг по управлению проектами пишутся, а сотни стартапов закрываются из-за неэффективного менеджмента
из-за неэффективного менеджмента
Из-за того, что какой-то известный дядька отрицает науку, а другой — рациональный подход, и тысячи хомячков, мнящих себя гениями, бегают за ними, отрицая здравый смысл.
Это к примеру, бывает всякое.
>Выбор ООП как терминологии выходит из составленной модели, а не наоборот.
>Кроме того, я не писал, что ООП — это самый полный и удобный способ описания модели.
Две противоречащие фразы. Так мы можем брать ООП и описывать любую модель, или только в определенных случаях выбирать его для описания модели?
>Из-за того, что какой-то известный дядька отрицает науку, а другой — рациональный подход, и тысячи хомячков, мнящих себя гениями, бегают за ними, отрицая здравый смысл.
Но ведь это и есть реальный мир? И в нем как-то нужно работать? Да и наука то, вещь непостоянная, ходят слухи. что мы знаем, что пока еще ничего не знаем?
Две противоречащие фразы.
Чем?
Так мы можем брать ООП и описывать любую модель, или только в определенных случаях выбирать его для описания модели?
Я писал что ООП всегда лучше? Или что ООП — самая универсальная парадигма? Нет. Нет, не писал.
И не напишу, так как ООП — это очередной инструмент, весьма удачный, но очень опасный. Как нож. Знаете, хорошим ножом можно сделать очень много чудесных вещей, но, по статистике, чаще всего ножами просто убивают.
Выбор, использовать ООП, ФП, СП или машинные коды — он определяется не предпочтениями программиста, а конкретной задачей. На микроконтроллеры, к примеру, писать на жаваскрипте хоть и можно, но, всё же, не стоит.
Но ведь это и есть реальный мир?
Нет, Нео.
И в нем как-то нужно работать?
Желательно, хорошо. Так, чтобы потомки могли воспользоваться плодами твоих трудов.
Да и наука то, вещь непостоянная, ходят слухи. что мы знаем, что пока еще ничего не знаем?
Я не слышал, чтобы Ньютоновскую физику опровергли. Дополнили и обобщили, да, но со времён Архимеда объём тела равен объёму вытесненной при погружении жидкости. И ни один Девид Копперфильд с этим ничего не смог поделать.
На самом деле не deus, а одушевленность https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D1%83%D1%88%D0%B5%D0%B2%D0%BB%D1%91%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C
Речь ведь не о создании симуляции мира, а о программировании. А это перевод естественных языков на машинные, так вот в естественных языках мы разделяем объекты (существительные) на тех, кто может инициировать действия и тех, кто «без души». Поэтому чисто структур (неживых объектов) не хватает, если только не представлять все в виде deus (функциональное программирование). Почему неудобно? Потому, что 2 ядра процессора — это уже 2 deus (тут можно спорить), а если нужно запрограммировать кучу различных устройств, взаимодействующих между собой, тот тут уже каждое из них — deus и если не давать им имена, то повторно использовать классы не выйдет и придется для каждого из них копировать один и тот же код.
Это ваше прочтение. Я же писал о «deus» как о неком излишнем углублении в процессы, описываемые программой. Например, распространение звука описывается гармоническими колебаниями молекул <и далее по тексту>. Однако, в 95% случаев, для нас достаточно описания распространения звука как регуляции громкости предзаписанного семпла квадратом расстояния от источника до центра, возможно, с искажением. А под «ex machina» имел в виду именно что определение на этапе проектирования необходимой глубины и точности декомпозиции, включая вывод некоторых из формул. Или хотя бы на этапе разработке, подпёртое эмпирическими оценками и здравым смыслом

То, что описываете вы, слабо относится и к ООП (в ООП нет и не может быть «одушевлённости», все объекты могут быть субъектами, посылая какие-либо сигналы окружающим объектам, а запуск программы, производимый одним из объектов, схож с древними мифами о происхождении Бытия), и к ФП. Если честно, я смутно понял ваш комментарий, и повторное перечитывание не особо спасает ситуацию.
Просто я говорю о программировании, т.е. переводе одних языков на другие, а вы о симуляции (о математике).
Вот, например, с ваших же слов, распространение звука описывается существительными «колебание» и «молекула», а также прилагательным «гармонические». Почему вы считаете, что компьютер(а по факту, операционная система и ее API), состоящий из процессора, памяти и т.д. и понятия не имеющий о волновой теории и логически не работающий по законам физики реального мира, должен понять язык математики лучше, чем любой другой язык?
Это вам проще оперировать этими терминами и абстракциями, а не всем в мире и компьютеру. И чем больше мы абстрагируемся от реальных устройств (привет, виртуальные машины и микросервисы), тем бессмысленнее становится опираться на физику реального мира.
И если вы не работаете в Intel, вам уже незачем думать подобным образом, чтобы программировать.
Вы эти выводы сделали основываясь на чём? На передёргивании одной части моих слов и умалчивании другой?

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

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

Архитектура компьютера — это часть инструмента. Подстраиваться ли под неё или нет — зависит исключительно из соотношения затрат и выгоды. Если пишется программа, которая должна отработать за 3 секунды — да, скорее всего, подстраиваться нужно; а если та, которая должно запуститься однажды и не важно, как долго она отработает, — видимо, нет.

В общем… Да ничего, в общем.
Эм, декомпозиция тоже производится словами, блоки тоже будут описываться словами.
Есть всего 2 варианта написания программ, сверху вниз, когда описываем СЛОВАМИ композицию, либо снизу вверх, когда уже имеющиеся слова (дано, такой-то компьютер с таким-то процессором) объединяем в группы и можем давать им новые названия (не важно, глаголы (функции), существительные (объекты) или прилагательные/дополнения (дженерики, монады и т.д.).
В зависимости от выбранных слов, выбирается инструмент для перевода этих слов на компьютерный язык. Тут нет никаких глобальных вещей или смысла.
А вы описываете моделирование (не знаю, видимо кубиками) в сферическом вакууме, поэтому слова вам кажутся неважными. Однако, и модель такая никому не нужна.
Словами ли? Или образами? Словами можно написать «f3 d3 e3 c3», но мелодию услышат единицы. Слова — инструмент выражения образов, и разные языки имеют разные выразительные способности. В том числе и языка программирования.
Декомпозиция — это не функция текста, это функция модели системы, на выходе которой совокупность частей системы и множество связей. Как они будут записаны, текстом, формулой или многомерной матрицей чисел, — зависит только от наших целей.
То, что описываете вы — частный, и, при этом, далеко не самый частый случай.
Самый, самый, не спорьте) Вот когда мы разовьем визуальное программирование (я вот мечтаю о трех или четырехмерном программировании), или звуковое, или мысленное (!), то и поговорим.
А формулы и матрицы — очень маленький раздел программирования, это математика, перенести ее не составляет труда.
Ни разу на собеседовании вообще меня не спросили, что такое ООП, если дело доходило до него, но спросили про инкапсуляцию, наследование и полиморфизм, атрибуты доступа, как это работает с наследованием и прочие технические детали целевой технологии

Потому что это надо знать, чтобы пользоваться языком программирования для решения задач. От того, что кто-то выучил фразу «ООП — это представление объектов окружающего мира», знание и умение программирования у него не появится.

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

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

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

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

class Cup extends Vessel implements Knob
{
    public function take(Holder $with)
}

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

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


Потому что это надо знать, чтобы пользоваться языком программирования для решения задач. От того, что кто-то выучил фразу «ООП — это представление объектов окружающего мира», знание и умение программирования у него не появится.

Знание синтаксиса еще не предполагает понимания парадигмы, ибо «на любом языке можно писать, как на фортране»
Насколько сильно негативное влияние отступления от trueООП для проекта?
Забавно. Мне 23 года, моё первое образование — токарь и мой первый серьезный проект был на битриксе.
Все страдания — вольный пересказ основных тезисов из книги Гради Буча (если не ошибаюсь). Я, как самоучка, начинал с нее и для понимания ООП мне вполне ее хватило. То, что сейчас считается ООП — это, с моей <непрофессиональной> точки зрения, бред сивой кобылы в безлунную ночь. То есть где-то в глубине присутствуют концепции ООП, но они так замаскированы «всяким обвесом», что начинаешь сомневаться в здравомыслии всех, кто это придумал и использует.

Это частное мнение, не надо холивара. Тому, кто родился и вырос «в этом», не понять, что «это» так ужасно — наоборот, все, что «не это» кажется ужасным — это естественно.
Неудачное время для поста, все холиварщики ушли в свеженький пост про vi :)
Существуют functional и nonfunctional требования; есть различные уровни абстракции (привет, hierarchy); сами абстракции — всего лишь относительная точка зрения на задачу; есть problem domain, а есть technology (язык программирования, например, с его идиомами, паттернами, best practices); есть сущности (реального мира), а есть зависимости между ними, которые могут сами выделяться в классы; и т.д. и т.п.
А здесь — чашки, стулья, двери…
Ну что мы в итоге поняли? ООП — это чашки, кружки, и ЗАВОД!.. На следующем собеседовании обязательно отвечу)
Сперва по тексту:
а Java лагает
Это всё из-за недо-ООП
С точки зрения меня, как программиста, мы хотим построить завод, который будет по заказу производить разнообразные чашки, кружки и бокалы.
И тут вдруг один завод по заповедям тру-ООП должен уметь всё это производить.
кастрированный ООП(привет Javascript, Go)
JS все-таки ОП, а не ООП.
инкапсуляцию, наследование, полиморфизм… Просто собралась куча дурачков и придумали три сложных слова...
Ну и на что будет похоже ООП, если это выкинуть из него?

На самом деле, просто ООП не умеют готовить. Вот некоторые проблемы:

Инкапсуляция. Ярчайший пример злоупотреблением — Java Beans. Которые не содержат ничего, кроме скрытых полей и простых методов доступа к ним. Они ничего не делают, но ведь ООП, делать публичные поля религия ООП не позволяет. Более того, чаще, чем желательно, из благоговейного трепета перед святой Инкапсуляцией зачастую плодят другие проблемы — нарушают принцип разделения ответственности, привносят кучу жестких зависимостей и т.д.

Наследование. Стоит ли упоминать, как умудряются делать длинные иерархии абстрактных классов, по чуть-чуть добавляя поведение, или, наоборот, делают общего предка у совершенно логически разных объектов только потому, что у них есть похожий код, вместо той же декомпозиции. Чуть менее известна проблема, когда делают абстрактный класс вместо интерфейса, заставляя наследоваться от него и переопределять поведение, чтобы оно работало как надо. И даже интерфейсы — проблема, когда у класса появляется 2 интерфейса с конфликтующей сигнатурой.

Полиморфизм
. Интересно, что на собеседованиях более всего затрудняются объяснить это слово, а на практике проблем с ним все же меньше. В основном, непонимание приводит к примерно такому коду:
try {
... 
} catch (Exception e) {
if(e instanceof RuntimeException) {
RuntimeException re=(RuntimeException) e;
...
}
}
И именно так можно изгадить ООП, но без этих принципов не обойтись. Еще хуже, что еще чаще объектами стали пользоваться как 1.структурами 2.процедурными модулями. Особенно часто такое доводилось видеть в PHP.
Но ООП от этого не перестает быть ООП. Можно писать плохо, можно писать хорошо. Можно придумать крутую архитектуру, а потом с болью наблюдать за ее конвульсиями и переписать все к чертовой матери, мало оглядываясь на ООП, шаблоны проектирования и другие умные аббревиатуры.

И да, мы, программисты, скорее инженеры-конструкторы, чем писатели, и это не зависит от парадигмы.
Sign up to leave a comment.

Articles