Всем привет!


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



Нотация и терминология


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


Краткое введение


На мой взгляд главная проблема ООП в том, что его понимают не с той стороны.


К сожалению, в XXI веке каждый день возрастает гребаная тенденция к воITи и информационное пространство просто наполняется однотипными историями, как вчера он на токарном станке вытачивал железки, а сегодня я успешный 23-летний сеньор с ПТУшным образованием на своей галере клепает убогие сайтики на Битриксе, получая золотые горы. Таким не объясняют, что такое ООП, им объясняют, что такое инкапсуляция, наследование и полиморфизм, и то, если повезет. А что за зверь такой ООП — ну и хер с ним собственно.


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


Ремарка

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


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


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


Собственно ООП


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


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


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


Комментарий к примеру и технические детали

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


abstract class Vessel
{
     private $material;
     private $liquid;

     public function __construct(Material $material)
     {
          $this->material = material;
     }

     public function fill(Liquid $liquid)
     {
          $this->liquid = $liquid;
     }

     public function pour()
     {
          $liquid = $this->liquid;
          $this->liquid = null;

          return $liquid;
     }
}

class Cup extends Vessel
{
    //Чем-то он отличается
}

class Wineglass extends Vessel
{
    //Чем-то он отличается
}

class Mug extends Vessel
{
    //Чем-то он отличается
}

class Human
{
    // тут что-то происходит
    public function drink(Vessel $vessel)
    {
         $this->stomack->add($vessel->pour());
    }
}

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


Кодяра
class VesselFactory
{
    //не самый изящный код, зато наглядненько. $className - это имя класса, который нам нужно получить от фабрики, $material - из чего сделать
    public function getVessel($className, $material)
    {
          return $className($material);
    }
}

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


Комментарий к примеру и технические детали

Интерфейс требует у объекта наличие поведения для внешнего взаимодействия. Интерфейс не обзятально толжен быть Able. Например, если наш компьютер имплементит интерфейс USB, то этот интерфейс не будет Usbabel(юэсбибэбл). Это будет USB интерфейс.


interface Knob
{
    public function take(Holder $with);
}

class Cup extends Vessel implements Knob
{
    public function take(Holder $with)
    {
         //Как-то мы можем держать стакан держателем
    }
}

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


Рассуждение


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


Мой опыт работы в одной команде с ребятами из UK, USA и EU показывает этот большой недостаток. Архитекторы и сеньоры всех пород и мастей, обладая невероятными технологическими познаниями, с трудом делают хорошую архитектуру(мы говорим про усредненный случай, есть множество гениальных ребят, которые такую красоту делают, что приходится дома под одеялом смотреть на их UMLы). Просто потому что следуют гайдлайнам, напрямую обозначенными в ООП. Но в жертву техническим деталям приносят куда более важные философские детали. Например, неправильно сделанная объектная декомпозиция системы превратит жизнь вашего разработчика в ад, даже если она сделана по всем гайдлайнам и согласно всем лучшим практикам. Обычно в этом случае получаются крутые классы с интерфейсами, фабриками, однако в них много, например, спагетти кода просто потому классов либо слишком мало(приходится их поведение превращать в условную логику) или слишком много(и приходится в условной логике хендлить разные виды классов). А там и экстендабилити страдает и склонность к алкоголизму растет.


Лучшая практика — это представить систему так, будто вы не программист, а строитель. Почему паттерны проектирования так хороши? Потому что они как раз таки позволяют абстрагироваться от технической реализации и создавать структуры у себя в голове такими, какими мы бы их делали не в коде, а используя гвозди, молоток и доски. Многие мои коллеги жаловались, что не поняли Банду Четырёх потому что там примеры кода на C++ или Smalltalk. Там идея совсем не в коде, на него вообще можно хер забить, там идея в том, что мы с вами можем строить программу так же, как и дом, и автомобиль. Понятным для человека образом, копируя инженерый гений из абсолютно других сфер. Программист сможет думать как инженер только тогда, когда начнет видеть матрицу вокруг. Декомпозировать предметы, которые его окружают, называть методы/интерфейсы/свойства всего, что попадается на глаза. Начиная от наших любимых кружек и заканчивая любимыми пиратами.


Дров в огонь подбрасывает то, что в современном мире миллионы языков, который либо предоставляют нам кастрированный ООП(привет Javascript, Go), либо технически ориентированный(C#, Java, C++), либо прекрасный и при этом пугающий своими возможностями(Python, Ruby), либо вообще PHP. И это не камень в огород этих языков, потому что у них есть назначение, применение и они хороши и пусть такими и будут.


Мои любимые языки

Python, C# и PHP. Просто потому что. Ещё я очень полюбил брейнфак, как язык с абсолютно нестандартным подходом, отлично подходит на собесы. Даешь за 30 минут написать прожку на брейнфаке, и тут сразу видно, насколько хорошо разработчик знаком со стандартными структурами данных, насколько у него развита логика и самое важное — насколько разработчик умеет учиться.


Заключение


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


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

Поделиться с друзьями
-->

Комментарии (114)


  1. Drag13
    04.08.2016 00:02
    +4

    Очередной пост боли и 250 сломанных к нему копий. Не нравится — учитесь. Или учите. А тратить нервы просто так, они не восстанавливаются.


    1. PaulTG
      04.08.2016 00:07
      -4

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


    1. samodum
      04.08.2016 01:35
      +2

      Старая байка.Нервы восстанавливаются.


  1. Alex_ME
    04.08.2016 00:07
    +4

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


    1. PaulTG
      04.08.2016 00:11

      Ну по сути да, но на мой взгляд DDD — это фреймворк для ООП как идеи.


    1. symbix
      04.08.2016 00:53
      +2

      SOLID+DDD это и есть реализация идеи ООП. О том и пост, кажется.


      1. PaulTG
        04.08.2016 00:54

        Вот вы, коллега, уловили идею


    1. Alew
      08.08.2016 12:01

      Встречал мнение, которое мне лично очень нравится, что DDD это способ делать ООП правильно.


      1. Alex_ME
        08.08.2016 12:48

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


  1. PkXwmpgN
    04.08.2016 00:18
    +26

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


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

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


    1. Zibx
      04.08.2016 03:34
      -7

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


  1. Nick_Maverick
    04.08.2016 00:39
    +2

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


    1. synedra
      04.08.2016 05:41
      +16

      Не думал, что мне когда-нибудь доведётся это написать, но:
      Гиперссылки не склоняются


      1. VioletGiraffe
        04.08.2016 23:51

        Отлично, новое правило современного языка :)


  1. deniskreshikhin
    04.08.2016 01:31
    +2

    Не надо вот из программистов делать инженеров. Это ни капли не инженерная специальность.

    Ну и что касается ООП, то Алан Кэй вполне чётко ответил и однозначно:

    OOP to me means only messaging, local retention and protection and
    hiding of state-process, and extreme late-binding of all things. It
    can be done in Smalltalk and in LISP. There are possibly other
    systems in which this is possible, but I'm not aware of them.

    Dr. Alan Kay on the Meaning of “Object-Oriented Programming”



    1. loz
      04.08.2016 01:58
      +6

      Ты и правда думаешь, что чтобы писать статью про то что ООП не работает — надо постараться и докопаться до истоков, изучить OOP в смолтолке, посмотреть хотябы пару не мейнстримных реализаций типа CLOS, IO? Разве стоит изучить серьезные научные работы на эту тему, типа https://www-master.ufr-info-p6.jussieu.fr/2006/Ajouts/Master_esj_2006_2007/IMG/pdf/Coin87.pdf? Нет, хабр и так сожрет.


      1. deniskreshikhin
        04.08.2016 02:11
        +1

        Хех, верно подмечено)

        Но не стоит особо автора винить в этом. Все-таки в РФ реально дела плохо обстоят с IT, особенно что касается теории программирования и языков, поэтому пусть так чем никак.


  1. loz
    04.08.2016 01:43
    +12

    Ещё я очень полюбил брейнфак, как язык с абсолютно нестандартным подходом, отлично подходит на собесы


    А еще это идиотизм


  1. loz
    04.08.2016 01:46
    -1

    Ну и вобще, автор еще зелен такие тексты писать. Если уж собрался критиковать ООП так хоть подойди с толком и грамотно. Например, так: https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53#.9iei73aa9


    1. heilage
      04.08.2016 05:30
      +5

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


      1. loz
        04.08.2016 10:15

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


        1. iCpu
          04.08.2016 10:58
          +3

          Да. Ибо это неверное использование инструмента.

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

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

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

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

          В общем, да, это неосиляторство.


          1. loz
            04.08.2016 23:06

            >А если ты переносишь часть кода между проектами — тут уж прости.

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

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

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

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

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

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

            Про move-семантику не знаю, честно, но как ссылки помогут в этом примере?


            1. iCpu
              05.08.2016 04:21

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

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

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

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


  1. heilage
    04.08.2016 05:41

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


  1. i360u
    04.08.2016 06:43
    +3

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


    1. arvitaly
      04.08.2016 09:20
      +1

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

      В свою очередь, современным крупнейшим системам становится недостаточно и трех измерений, так рождается dependency injection, модульность, настройки компилятора c++ и т.д.
      Что интересно, это вовсе не вопрос синтаксиса, а значит lisp-подобный язык в итоге позволил бы создавать ПО любой мерности. Боюсь только, человеческий мозг с таким уже не справится.


  1. iCpu
    04.08.2016 07:08
    +5

    > Интерфейс требует у объекта наличие поведения для внешнего взаимодействия
    > 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-х дюймовым крюком объект можно взять. Важно, что объект может только производить действия, он не может действоваться другим объектом.

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


    1. MonkAlex
      04.08.2016 07:42

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

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


      1. iCpu
        04.08.2016 07:56
        +1

        > А это значит, что взять кружку — навык, а не способность. У человека почти всё навыки, ибо этому учится.
        > > Кружка, как и ручка, должна иметь физические параметры. Брать — работа держальника, и уже он по физическим параметрам должен определять, возьмётся кружка или нет.
        Где противоречие?

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


        1. MonkAlex
          04.08.2016 08:08
          -1

          Это вопрос реализации.

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

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

          Да, пример в статье оторван от реальности, но он таки реализует какую то логику с какой то целью, вы не можете однозначно утверждать, что это неправильная реализация. Реализация зависит от цели.


          1. iCpu
            04.08.2016 08:24

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


            1. MonkAlex
              04.08.2016 08:39
              -1

              Если разработка идёт по о кружках, то интерфейсы вида «Кружка берется» обычно оказываются удобнее, чем какие то свойства размер\вес\форма по которым кто-то сам будет разбираться, сможет ли взять.

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


              1. iCpu
                04.08.2016 09:10
                +5

                Вот после таких вот допущений людят уходят в мона… кхым… в функциональное программирование.

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

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

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


                1. MonkAlex
                  04.08.2016 10:49

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

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


                  1. iCpu
                    04.08.2016 11:14

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

                    И нет, разница в том, как реализован метод и к кому он привязан, есть, и огромная. Почитайте комментарий выше ещё раз, если для вас это не очевидно.


                    1. MonkAlex
                      04.08.2016 13:35

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


                      1. iCpu
                        04.08.2016 19:27

                        Скажите, как то, что в кружку встроен шокер, влияет на её способность «браться». Не на возможность «быть взятой», а именно «браться»?
                        Если в кружке есть шокер, значит, интерфейс будет сложнее, нужно добавить метод 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, и даже имеет право их токнуть в любой момент времени, если реализует интерфейс шокера. Но «взяться» она по прежнему не способна, ей нечем. Она может «быть взята», и «взять» по прежнему реализует «рука»


                        1. MonkAlex
                          04.08.2016 19:37

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


                          1. iCpu
                            04.08.2016 20:02
                            +2

                            Не нужно мне делать одолжений, прав я или не прав. Я привязался не к слову, а к дырке в логике. Если для вас дырки нет, советую серьёзно задуматься над изучением простейшего логического аппарата и основе декомпозиции систем.


                1. vintage
                  06.08.2016 11:27
                  +1

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


                  1. iCpu
                    06.08.2016 13:53

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


                    1. vintage
                      06.08.2016 14:56

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


                      1. iCpu
                        06.08.2016 15:09

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

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


                        1. iCpu
                          06.08.2016 15:15

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


                        1. vintage
                          07.08.2016 01:15

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


                          1. iCpu
                            07.08.2016 08:18

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


                            1. vintage
                              07.08.2016 11:20

                              Меньшее зло, чем 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 ) ) );


                              1. iCpu
                                07.08.2016 16:46

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


                                1. vintage
                                  07.08.2016 17:36

                                  А вы знаете другой способ отказаться от библиотек?

                                  Конечно:


                                  import my.super.puper.lib;

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

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


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

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


                                  1. iCpu
                                    07.08.2016 18:31

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

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

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


                                    1. vintage
                                      07.08.2016 23:54

                                      Или это просто красивый способ обозначить отсутствие ответа?

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


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

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


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

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


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

                                      Например?


                                      1. iCpu
                                        08.08.2016 06:41

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

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

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

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


                                        1. vintage
                                          09.08.2016 12:21

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

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


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

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


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

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


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

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


                                          1. iCpu
                                            09.08.2016 15:32

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

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

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


                                            1. vintage
                                              09.08.2016 21:01

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


                                              1. iCpu
                                                11.08.2016 07:50

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


                                                1. vintage
                                                  11.08.2016 09:13

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


                                                  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)
                                                  }


                                                  1. iCpu
                                                    11.08.2016 10:26

                                                    > Ну, вам, наверно, виднее как ООП работает, а как — нет.
                                                    Читайте внимательнее
                                                    >> и владелец метода в одной из реализаций
                                                    Я не спорю в форме выражения мысли. Языки могут быть разными: lisp, java, c++, английский, русский, китайский и многие многие другие. Я, по непониманию сути вашего первого комментария (на тот момент я действительно подумал, что вы сетуете за эквивалентность разных сигнатур) с вами поспорил, но, когда до меня дошло, я сразу вам написал, что нам с вами спорить не о чем, это манера речи, не более.

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


    1. Sing
      04.08.2016 11:27

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

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

      Хотя пример нарушает принцип единственной обязанности (SRP, который в SOLID первый, т.е. S).


    1. Alew
      08.08.2016 15:14

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


      1. iCpu
        08.08.2016 20:51

        Вы вкладываете в мои уста чужие слова и начинаете с ними жарко спорить. При этом не видите очевидных прорех. Чем больше я получаю подобных комментариев, тем сильнее убеждаюсь в том, что мне имеет смысл попробовать себя в проектировщиках.

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

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

        Если короче, ООП должно идти в обнимку с SOLID и DDD. Как и ФЯП должны идти в обнимку с мат. выкладками, а xml/json — с валидными схемками.


        1. Alew
          08.08.2016 22:12

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


          1. iCpu
            09.08.2016 05:46

            Не обязательно драться с ветряными мельницами, но вот ваш комментарий, а выше моя ветка с vintage'ом, и вот все трое из нас сидят на привале, и вокруг каждого из нас бегает свой Санчо.

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

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


            1. Alew
              09.08.2016 10:48

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


              1. iCpu
                09.08.2016 11:01

                Согласитесь, что этот пример вынут из известного места, и я уже описал узкие места такого дизайна, так что повторяться не вижу смысла, что до Пети, мне не попадалось его книг. ничего не имею сказать.
                И, если что, я привёл пример, при котором кружка может иметь свою руку. В этом случае интерфейс становится, мягко говоря, неоднозначным, что явно свидетельствует против него.

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


                1. Alew
                  09.08.2016 11:27

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


                  1. iCpu
                    09.08.2016 17:27

                    > В системе где объект рука посылает сообщение объекту кружка
                    Нет никаких проблем. Но ведь я придрался к системе, в которых КРУЖКА посылает сообщение РУКЕ, выступая инициатором. Не отвечает на сообщение, а именно инициирует. Почитайте пример в очередной раз, в очередной раз перечитайте все эти тупые деревья комментариев.


                    1. Alew
                      10.08.2016 10:12

                      cup.take(holder)?


                      1. iCpu
                        10.08.2016 17:10

                        Кто в этом листинге посылает кому сообщение? Кто выступает инициатором?


                        1. Alew
                          11.08.2016 17:24

                          В том что я привел, инициатор не указан, а получатель сообщения очевидно cup. Но если предполагается отправка сообщения от руки кружке, то эта строка должна вызываться внутри одного из методов руки в виде cup.take(this). Как то так.


                          1. iCpu
                            11.08.2016 17:31

                            ООП отличается тем, что достаточно просто транслируется в естественный язык.
                            «cup.take(holder)»
                            «cup take holder»
                            «Кружка возьми\берёт\взять держатель»
                            Пожалуйста, ответьте мне, где с точки зрения естественного языка подлежащее, сказуемое, дополнения и тп. Ответьте, насколько с точки зрения естественного языка грамотно это предложение.


                            1. Alew
                              12.08.2016 00:43

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


                              1. heilage
                                12.08.2016 04:51

                                У вас же наверняка есть пример, по которому можно составить сравнение декомпозиций в плане понятности? Без примера — голословно.


                                1. Alew
                                  12.08.2016 12:20

                                  Готового примера нет, есть общие соображения. Функциональную декомпозицию в состоянии выполнить любой человек обладающий алгоритмическим мышлением, в то время как объектная требует определенных навыков. Тут например http://www.wirfs-brock.com/PDFs/How%20Designs%20Differ.pdf автор сравнивает свое видение мира с тем, которое на мой взгляд, получило наибольшее распространение. Централизованный контроль проще понять, но Wirfs-Brock выступает за децентрализацию контроля, а потом проходит 10 лет и появляется вот это https://en.wikipedia.org/wiki/Data,_context_and_interaction где говориться, что взаимодействие объектов нельзя децентрализовывать. Короче, все сложно.


                                  1. iCpu
                                    12.08.2016 12:51

                                    Готового примера нет, есть общие соображения.
                                    Пруфов нет, но вы держитесь!
                                    Функциональную декомпозицию в состоянии выполнить любой человек обладающий алгоритмическим мышлением, в то время как объектная требует определенных навыков.
                                    https://habrahabr.ru/post/251089/
                                    Wirfs-Brock выступает за децентрализацию контроля
                                    В ООП мы описываем предметную область — большой сложный объект. Соответственно, всё, что в неё включено, является полями главного объекта, а связи — определяются методами главного объекта.
                                    Это нам говорит системный анализ.


                                    1. Alew
                                      12.08.2016 13:33

                                      Если вы потрудитесь походить по моим ссылкам, то обнаружите что «Wirfs-Brock выступает за децентрализацию контроля» а Trygve Reenskaug и James O. Coplien утверждают что децентрализованное управление менее понятно. Я понимаю, что эти люди не для всех являются авторитетами, но кроме этого я могу только ссылаться на здравый смысл, который должен подсказывать, что централизованный контроль должен быть проще для понимания чем децентрализованный. Это ваше дело, считать это пруфами или нет, но других я предложить не могу.
                                      Я не понял что доказывает ваша ссылка.

                                      В ООП мы описываем предметную область — большой сложный объект. Соответственно, всё, что в неё включено, является полями главного объекта, а связи — определяются методами главного объекта.
                                      Это нам говорит системный анализ.

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


                                      1. iCpu
                                        12.08.2016 15:37

                                        Оффтоп
                                        Слава яйкам, я снова могу в теги!


                                        1. symbix
                                          12.08.2016 18:02

                                          Да что там советские ученые, элементы системного анализа были известны уже в Древней Греции :)


                                          1. iCpu
                                            12.08.2016 18:12

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


                                            1. symbix
                                              12.08.2016 19:51

                                              Эвансу или Вирту вряд ли, а нынешним двадцатилетним senior-ам — запросто. :)


                                        1. Alew
                                          13.08.2016 00:40

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


                                          1. iCpu
                                            13.08.2016 06:15

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


                                            1. Alew
                                              13.08.2016 08:56

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


                                              1. iCpu
                                                13.08.2016 10:45

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

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


                                                1. Alew
                                                  13.08.2016 11:28

                                                  Я прочитал статью в википедии, мне достаточно того что это еще одна формальная методология. Я не понимаю как можно было не заметить что West отрицает формальные методологии. Это все хорошо в теории, на практике я ни разу ничего подобного не видел. Но может быть вы мне ткнете пальцем где написано что какие то известные компании используют эту методологию? Ну не возможно, чтобы все это использовали и при этом нигде ничего об этом написано не было.
                                                  Это ваше мнение про «базовость» я с ним не согласен, нужна ссылка.
                                                  Давайте без «наводок», прямой вопрос, прямой ответ. Но потрудитесь привести источники.
                                                  Вам свойственно делать сомнительные логические заключения, и обвинять собеседников в безграмотности.
                                                  При этом на вопрос о классе со 100500 полями вы зачем-то приводите какую-то ерунду, на на уточняющий вопрос ссылаетесь на NDA. Это совершенно не конструктивное поведение. Не знаете как выйти из диалога? Продолжайте в той же манере и я просто перестану вам отвечать.


                                                  1. iCpu
                                                    13.08.2016 12:51

                                                    Я не понимаю как можно было не заметить что West отрицает формальные методологии

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

                                                    https://ru.wikipedia.org/wiki/Система
                                                    https://ru.wikipedia.org/wiki/Объектно-ориентированное_программирование
                                                    Если найдёте, где я вышел за рамки определений и основных понятий, зовите.
                                                    При этом на вопрос о классе со 100500 полями вы зачем-то приводите какую-то ерунду
                                                    100500 полей? Просто контейнер элементарных частиц и метод calculatePhysics. Что считать элементарным — другой вопрос, относящийся уже к проектируемой модели.


                                            1. arvitaly
                                              13.08.2016 09:43

                                              У любой нашей системы, кроме вселенной есть внешние объекты, которые не являются частью нашей системы, но с которыми мы можем/должны взаимодействовать. Эти объекты не подчиняются нам напрямую, мы можем лишь косвенно стимулировать (например, API Facebook отвечает только по токену, но токен может быть заблокирован). Мало того, в крупных системах невыгодно централизовывать управление, слишком много накладных расходов. Поэтому жертвуют точностью и гарантированностью результата в пользу объемов. Именно поэтому операционные системы такие ненадежные и уязвимые. Это не хорошо и не плохо, но это показывает, что в реальном мире выгоднее всего действовать так. Мало того, наш мозг чаще свего действует не по строгой инструкции, а накапливает ошибки и ставит заплатки.
                                              А программирование — есть процесс переноса мыслей, путем приблизительных слов, компьютеру. А это означает, что если мы сможем описывать задачи сразу со 100% управлением всеми ресурсами, то нам не понадобится программирование — компьютер и так будет все понимать.


                                              1. iCpu
                                                13.08.2016 10:11

                                                Наше приложение и facebook образуют единую систему, но они обособлены друг от друга. Для отображения поведения facebook у вас есть локальный класс, реализующий хранение данных с сервера и подмножество API. Именно этот класс и будет классом управления, он будет составной частью вашей подсистемы и будет существовать в ней вне зависимости от доступности серверов facebook.
                                                ООП не противоречит разнесению системы на несколько приложений, не противоречит передачи сообщений через сокеты в виде json.
                                                ООП не запрещает использовать ленивые или распределённые механизмы, это всё вообще никак не пересекается с ООП.

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

                                                А это означает, что если мы сможем описывать задачи сразу со 100% управлением всеми ресурсами, то нам не понадобится программирование — компьютер и так будет все понимать.
                                                Поясните, мне просто непонятны взаимосвязь доступности ресурсов и компьютерной логики.
                                                Например, вы наняли дюжину детей Азии на стройку. У вас есть ресурсы, есть схемы и наглядные материалы, но как это поможет объяснить этим самым детям, чего вы от них хотите?


                                                1. arvitaly
                                                  13.08.2016 10:48

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

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


                                                  1. iCpu
                                                    13.08.2016 11:51
                                                    +1

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

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

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

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

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


                                                    1. arvitaly
                                                      13.08.2016 12:31

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


                                                      1. iCpu
                                                        13.08.2016 13:00

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

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


                                                        1. arvitaly
                                                          13.08.2016 13:48

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


                                                          1. iCpu
                                                            13.08.2016 16:52

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


    1. arvitaly
      10.08.2016 04:16

      На самом деле не 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 и если не давать им имена, то повторно использовать классы не выйдет и придется для каждого из них копировать один и тот же код.


      1. iCpu
        11.08.2016 10:46

        Это ваше прочтение. Я же писал о «deus» как о неком излишнем углублении в процессы, описываемые программой. Например, распространение звука описывается гармоническими колебаниями молекул <и далее по тексту>. Однако, в 95% случаев, для нас достаточно описания распространения звука как регуляции громкости предзаписанного семпла квадратом расстояния от источника до центра, возможно, с искажением. А под «ex machina» имел в виду именно что определение на этапе проектирования необходимой глубины и точности декомпозиции, включая вывод некоторых из формул. Или хотя бы на этапе разработке, подпёртое эмпирическими оценками и здравым смыслом

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


        1. arvitaly
          11.08.2016 11:00

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


          1. iCpu
            11.08.2016 11:26

            Вы эти выводы сделали основываясь на чём? На передёргивании одной части моих слов и умалчивании другой?

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

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

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

            В общем… Да ничего, в общем.


            1. arvitaly
              11.08.2016 12:20

              Эм, декомпозиция тоже производится словами, блоки тоже будут описываться словами.
              Есть всего 2 варианта написания программ, сверху вниз, когда описываем СЛОВАМИ композицию, либо снизу вверх, когда уже имеющиеся слова (дано, такой-то компьютер с таким-то процессором) объединяем в группы и можем давать им новые названия (не важно, глаголы (функции), существительные (объекты) или прилагательные/дополнения (дженерики, монады и т.д.).
              В зависимости от выбранных слов, выбирается инструмент для перевода этих слов на компьютерный язык. Тут нет никаких глобальных вещей или смысла.
              А вы описываете моделирование (не знаю, видимо кубиками) в сферическом вакууме, поэтому слова вам кажутся неважными. Однако, и модель такая никому не нужна.


              1. iCpu
                11.08.2016 14:38

                Словами ли? Или образами? Словами можно написать «f3 d3 e3 c3», но мелодию услышат единицы. Слова — инструмент выражения образов, и разные языки имеют разные выразительные способности. В том числе и языка программирования.
                Декомпозиция — это не функция текста, это функция модели системы, на выходе которой совокупность частей системы и множество связей. Как они будут записаны, текстом, формулой или многомерной матрицей чисел, — зависит только от наших целей.
                То, что описываете вы — частный, и, при этом, далеко не самый частый случай.


                1. arvitaly
                  11.08.2016 14:50

                  Самый, самый, не спорьте) Вот когда мы разовьем визуальное программирование (я вот мечтаю о трех или четырехмерном программировании), или звуковое, или мысленное (!), то и поговорим.
                  А формулы и матрицы — очень маленький раздел программирования, это математика, перенести ее не составляет труда.


  1. michael_vostrikov
    04.08.2016 07:35
    +8

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

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

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

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

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

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

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

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

    Мне вот из этого кода кажется, что чашка берет держатель. Как-то не очень это передает концепцию ООП.


    1. Alew
      08.08.2016 17:07

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


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

      Знание синтаксиса еще не предполагает понимания парадигмы, ибо «на любом языке можно писать, как на фортране»


  1. pengyou
    04.08.2016 08:19
    +3

    Так что же такое ООП, ув. автор?


  1. keslo
    04.08.2016 08:58

    Насколько сильно негативное влияние отступления от trueООП для проекта?


  1. MadridianFox
    04.08.2016 09:08
    +7

    Забавно. Мне 23 года, моё первое образование — токарь и мой первый серьезный проект был на битриксе.


  1. sim-dev
    04.08.2016 09:51

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

    Это частное мнение, не надо холивара. Тому, кто родился и вырос «в этом», не понять, что «это» так ужасно — наоборот, все, что «не это» кажется ужасным — это естественно.


  1. maxru
    04.08.2016 11:48

    Неудачное время для поста, все холиварщики ушли в свеженький пост про vi :)


  1. junkerSchmidt
    04.08.2016 12:02

    Существуют functional и nonfunctional требования; есть различные уровни абстракции (привет, hierarchy); сами абстракции — всего лишь относительная точка зрения на задачу; есть problem domain, а есть technology (язык программирования, например, с его идиомами, паттернами, best practices); есть сущности (реального мира), а есть зависимости между ними, которые могут сами выделяться в классы; и т.д. и т.п.
    А здесь — чашки, стулья, двери…


  1. S3Ga
    04.08.2016 12:02
    +2

    Ну что мы в итоге поняли? ООП — это чашки, кружки, и ЗАВОД!.. На следующем собеседовании обязательно отвечу)


    1. lovermann
      04.08.2016 21:26

      Я всегда так и говорю!


  1. franzose
    04.08.2016 14:23

    Стиль изложения похож на ebanoe.it.


  1. Lure_of_Chaos
    05.08.2016 13:08
    +1

    Сперва по тексту:

    а Java лагает
    Это всё из-за недо-ООП
    С точки зрения меня, как программиста, мы хотим построить завод, который будет по заказу производить разнообразные чашки, кружки и бокалы.
    И тут вдруг один завод по заповедям тру-ООП должен уметь всё это производить.
    кастрированный ООП(привет Javascript, Go)
    JS все-таки ОП, а не ООП.
    инкапсуляцию, наследование, полиморфизм… Просто собралась куча дурачков и придумали три сложных слова...
    Ну и на что будет похоже ООП, если это выкинуть из него?

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

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

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

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

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