ООП: Кто взял Измаил? Вопрос принадлежности методов объекту

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

Это распространённая тема для холиваров. Например:
Не используйте ООП. Никогда. Это ошибка.

На эту тему есть много материалов, к примеру: www.youtube.com/watch?v=QM1iUe6IofM

Если ООП все еще кажется вам хорошей идеей, то решите простую задачку.

Есть три объекта: кошка, кормушка и человек. Вам необходимо написать метод, который бы позволял человеку покормить кошку, воспользовавшись кормушкой.

Вопрос: методом какого класса будет являться метод.покормить()?

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

Теперь сравните это с функциональной реализацией: у вас есть функция покормитьКошку() принимающая в качестве аргумента ссылку на кошку и кормушку.
Цитата из холивара

Как ответить на данный вопрос?

Вначале давайте рассмотрим пример из физики.

Кейс 1 (из физики): закон Ома


Закон Ома: I=U/R, где I — сила тока, U — напряжение, R — сопротивление.

Несложно заметить, что закон Ома, как и любую другую формулу из трех переменных, можно записать тремя способами: I=U/R, R=U/I, U=IR. Как выработать правило, позволяющее однозначно определить единственную форму записи? Очень просто: надо записать с левой стороны производную величину, т.е. ту, которая становится имеющей определённое значение, в зависимости от остальных величин.

I=U/R «Сила тока СТАНОВИТСЯ равной отношению напряжения на концах проводника к сопротивлению проводника» — верно.

U=IR «Напряжение на концах проводника СТАНОВИТСЯ равным его сопротивлению, умноженному на силу тока через проводник» — не верно.

R=U/I «Сопротивление проводника СТАНОВИТСЯ равным отношению напряжения на концах к силе тока» — не верно.

Видите — как только мы условились, что производное значение находится слева, остался только один вариант.

Вот так же, мы поступим и в ООП. Условимся, что метод принадлежит тому, кто воздействует:

Кто_действует.Метод(Объект_воздействия);


Кейс 2: Кто взял Измаил?


Следовательно, при ответе на вопрос «Кто взял Измаил?» с точки зрения объектно ориентированного программирования, и с позиции «кто воздействует?», правильный ответ будет Суворов.ВзятьКрепость(Измаил, Турки):boolean. Все другие варианты, такие как: Турки.Про***тьКрепость(Измаил, Суворову), Измаил.СменаСобственника(Турки, Суворов), АбстрактнаяКрепость.БытьЗахваченной(Исмаил, Суворов, Турки) и т.д. — все эти варианты не верны.

Кейс 3: Человек, кормушка и кошка



«Покорми кошку!» с сайта corchaosis.ru

Человек насыпал еды в кормушку. Это метод:
Человек.НасыпатьЕдыКошке(ПакетЕды,Кормушка). При выполнении метода, в глобальной переменной ПакетЕды количество еды уменьшается, а в глобальной переменной Кормушка появляется.

А как же кошка? А кошка существует ДО вызова метода НасыпатьЕдыКошке, как условие его вызова. Если кошка на даче, то и метод НасыпатьЕдыКошке вызываться не будет.

Кейс 4: Игрок в DOOM, шотган и монстр


Допустим, что вопрос попадания в монстра не имеет градаций: либо попал, либо не попал.
Правильная реализация. Всё начинается с метода Игрока:

Игрок (либо, Игрок_1 в многопользовательской игре).Выстрел(Монстр_1)
Внутри реализации метода Выстрел, мы видим, что текущее оружие игрока — шотган.
Следовательно, вызываем метод вложенного объекта:

Игрок_1.Оружие[Игрок_1.Номер_выбранного_оружия].Выстрел(Монстр_1)

Игрок_1.Оружие — это класс TWeapon.

В данном случае, вызывается метод класса TShotgun, который является дочерним к TWeapon.
Итак, имеем: Шотган.Выстрел(Монстр_1)

Шотган, при выполнении данного действия, изменяет внутреннее состояние: для шотгана это количество патронов (а для другого вида оружия могла бы быть, например, и температура). Также, мы определяем силу урона — так, шотган стреляет по 2 патрона, но может выстрелить и один, если в заряде остался только один патрон.

Если бы мы выстрелили из ракетницы, то появился бы новый объект — ракета. Со своим методом Tick, обрабатывающим действия за один тик игрового времени (игровое время изменяется, обычно, в тиках). Но мы выстрелили из оружия, поражающего без задержки, поэтому — знаем количество выстреленных патронов (1 или 2), знаем расстояние (сравнивая Игрок.Position и Монстр_1.Position), и внутри метода класса Шотган, рассчитываем ущерб.

И, наконец, Монстр_1.НанесёноПовреждение(сила_повреждения:Float). Теперь, как и перед этим шотган менял внутреннее состояние (кол-во патронов), теперь Монстр_1 меняет внутреннее состояние Монстр_1.Здоровье, и сценарий поведения (особенно, если Здоровье стало меньше нуля).

Итак, мы видим, что благодаря ООП, мы можем легко добавить новое оружие: достаточно описать его как дочерний класс от TWeapon, определить Выстрел и разместить на карте. Класс Игрок уже умеет подбирать и добавлять в свой игровой набор объекты TWeapon. Всё. Хотя нет, не всё. Если оружие будет дарить монстрам цветочки, заставляя их влюбляться в игрока, то и монстрам следует прописать метод ОтветитьНаПризнаниеВЛюбви:boolean, а также набор других методов — в зависимости от степени проработки, в этом случае вам может потребоваться и ряд новых ООП объектов и их методов.

Кейс 5: Потрогать руками — это функция или метод


Не только ответ на этот вопрос, но и сам интерфейс взаимодействия, очевидно, находится в зависимости от трогаемого объекта.

Потрогать_руками::дом — это функция.

Потрогать_руками:: ноутбук — это метод объекта «ноутбук». Вы должны использовать интерфейс, чтобы вызвать методы ноутбука «KeyDown, KeyUp, KeyPressed» передав в эти методы правильные данные: какая кнопка была нажата, в какой момент времени и т.д.

Потрогать_руками::огонь — это метод объекта «вы». Вам необходим объект «self», изменение состояние которого правильно опишет ожог руки. Огонь состояния не изменит.

Думаю, вы и сами можете продолжить список интерфейсов объектов, которые можно потрогать руками, с целью получения практики использования объектно-ориентированного программирования.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 398

    +26
    Холивар из предисловия рождается как правило из ложного тезиса, что ООП это моделирование объектов реального мира. Но ООП совсем не про то, ООП это моделирование абстракций исходя из контекста конкретной задачи. Никакого реального мира, это маркетинговый буллщит из времен, когда надо было продвигать ООП-языки на рынок.
      +4
      Тут нет никакого противоречия, потому что в холиварных примерах обычно посылка именно такая, «замоделировать мир». Да и в целом задача моделирования какой-то области реальности в коде — весьма нередка.
        0

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


        В общем, любой фанатизм хорош в меру.

        +2

        Все нормально моделируется в объектах реального мира. Просто методы должны быть в обоих объектах — отдающий и принимающий.


        class Человек
        {
            method накормитьКошку()
            {
                var корм = this->взятьКорм();
                this->положитьКормВКормушку(корм)
        
                this->позватьКошку();
            }
        
            method взятьКорм()
            {
                var пакетКорма = this->найтиПакетКорма();
                var корм = пакетКорма.взятьКорм();
        
                return корм;
            }
        
            method положитьКормВКормушку(Корм корм)
            {
                this->кормушка->добавитьКорм(корм);
            }
        
            method позватьКошку()
            {
                this->сказать("Кис-кис-кис");
                ...
            }
        
            ...
        }
        
        class Кормушка
        {
            method добавитьКорм(Корм корм)
            {
                ...
            }
        }
        
          0

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

            +1

            Сходить за кормом :)

              +3

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


              class Кормушка
              {
                  int количествоКорма;
              
                  method добавитьКорм(Корм корм)
                  {
                      this->количествоКорма += корм.количество;
                  }
              }

              Вообще можно и снаружи писать кормушка->количествоКорма += корм.количество, с точки зрения моделирования нет большой разницы. '+=' можно считать методом типа int, то есть тоже есть какая-то цепочка вызовов.

                0

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

                  –1

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

                    0

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

                  0
                  Кормушка должна уметь принять/отдать корм и выдать свой статус. Все, на
                  этом ее функционал закончен.
                0
                А где класс Кошки, у которой есть метод Кушать, который в качестве аргумента может принимать Кормушку?
                  0

                  Там примерно то же самое, моделируем передачу какого-то объема корма из кормушки кошке. Суть в том, что информационные объекты моделируют реальные.

                    0
                    Кошка должна проверить голодна ли она, и должна проверить наличие корма в кормушке.
                  0
                  Что-то я не улавливаю семантику свойства `кормушка` у объекта `человек`.
                    0

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

                +10
                Несложно заметить, что закон Ома, как и любую другую формулу из трех переменных, можно записать тремя способами: I=U/R, R=U/I, U=IR

                И все три записи будут верными. Если известны две величины, то мы можем вычислить третью. И ничего более.
                U=IR «Напряжение на концах проводника СТАНОВИТСЯ равным его сопротивлению, умноженному на силу тока через проводник» — не верно.

                Если через резистор R пропускать ток силой I, то падение напряжения на резисторе будет равно U.
                Ну и так далее.

                  –8
                  И все три записи будут верными

                  Задача была — сделать вариант записи единственным.

                  Если через резистор R пропускать ток силой I, то падение напряжения на резисторе будет равно U.

                  Если вы умеете через резистор R пропускать ток силой I, не прикладывая напряжение, то да, в результате этого оно возникнет конечно… Наверно, так можно описать динамо-машину.
                    +14
                    В электротехнике (в моделях) есть генератор напряжения и генератор тока. Генератор тока гонит ток во внешнюю цепь. А какое там получится напряжение, зависит уже от сопротивления цепи.
                    То есть вариант записи зависит от ситуации, от решаемой задачи.
                      +4

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

                      +2

                      Э-э-э, а откуда возникает требование "не прикладывая напряжение", которое прямо противоречит формуле?

                        0

                        "Становится" в примерах автора несет причинно-следственную связь, а не только описывает факт равенства.


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

                          +1

                          В том-то и дело, что причинно-следственных связей эта формула не даёт. Сопротивление — да, само по себе, а вот и ток, и напряжение порождаются одними и теми же свободными электронами.


                          В некотором смысле причиной возникновения как напряжения, так и тока можно считать ЭДС, которая в формуле U = IR отсутствует.

                            0
                            на самом деле всегда можно дать такое напряжение, что и R поменяется. А ещё R зависит от частоты, если ток переменный. Так что и R = U/I имеет право на существование.
                              –1
                              Любое утверждение имеет область действия, некорректно требовать чтобы оно оставалось верным вне своего контента. Вы можете победить в шахматах используя молоток, но в правилах игры этого нет и не будет. Сжигание резистора высоким напряжением — это использование молотка в шахматах.
                            +1

                            А, например, в формуле связи градусов Фаренгейта с градусами Цельсия какая причинно-следственная связь? Фаренгейты меняются как результат изменения Цельсиев, или наоборот?


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

                              0
                              Поддерживаю вас!
                              Если эту мысль рассматривать в контексте программирования, то в теории категорий (и в целом в математике) такие преобразования называются изоморфизмом:

                              A ⭢ B
                              B ⭢ A


                              Т.е. мы можем однозначно преобразовать из одного типа в другой и обратно, не потеряв информации.
                          +4
                          Если вы умеете через резистор R пропускать ток силой I, не прикладывая напряжение, то да, в результате этого оно возникнет конечно…

                          «Прикладывание напряжения U» никак принципиально не отличается от «пропускания тока I» — ни в физике как таковой, ни в реальной электронике. Есть объекты, которые хорошо делают первое, есть которые хорошо делают второе.
                            –1
                            Есть сопротивление, у него есть два контакта. Вы прикасаетесь ими к источнику напряжения. Вот, вы приложили напряжение к резистору.

                            Теперь, расскажите, как именно вы напрямую приложите к резистору силу тока.
                              +1
                              Есть сопротивление, у него есть два контакта. Вы прикасаетесь ими к источнику напряжения. Вот, вы приложили напряжение к резистору.

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


                              Теперь, расскажите, как именно вы напрямую приложите к резистору силу тока.

                              Прикладываю резистор к источнику тока и включаю источник тока.

                                0

                                Насколько я помню электротехнику (25+ лет назад), источники напряжения — это различного рода химические генераторы элекктричесвта — батарейки, проще говоря, а источники тока — "физические" генераторы, базирующая на электромагнитных явлениях, прежде всего на электростанциях. Что розетка ведёт себя как источник напряжения в бытовых сценариях — просто "случайное" соотношение различных сопротивлений полной системы.

                          +10
                          Вот так же, мы поступим и в ООП. Условимся, что метод принадлежит тому, кто воздействует

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

                          • UFO just landed and posted this here
                              +1
                              У вас как-то однобоко вышло. По вашей логике, и человек не должен знать, кого он кормит, потому что у него есть кормушка.
                                0

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

                                  0

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

                                  • UFO just landed and posted this here
                                      0
                                      Кошка накормлена или нет, можно определить узнав состояние кошки, или состояние кормушки.
                                      вызов метода «покормить» может закончиться только двумя исходами:

                                      Забыли про:
                                      3. Ожидание: кошка не проголодалась
                                        0

                                        Это одна из причин неудачи. Если хозяйка кошки меня спрашивает "я просила накормить кошку в полдень, ты накормил?", то ответ "я насыпал ей корма и теперь ожидаю, пока она захочет есть" по опыту приравнивается к "Не накормил".

                                        • UFO just landed and posted this here
                                          0
                                          Это уже метод не объекта, но сервиса. Объекты не нетвечают друг за друга, а только используют. Если человеку дать корм и кормушку — он положит корм в кормушку. Если дать корм и кошку — то корм будет положен в кошку. Если дать кормушку и кошку… ну вы поняли.

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

                                          В них мы можем реализовывать уже более сложные стратегии — начиная от генерации ошибки, если кормушка не пустая перед началом следующего кормления и заканчивая измерением глюкозы в крови кошки в процессе питания и привязкой человека к кошке, пока эта глюкоза не окажется в заданных пределах.
                                          0
                                          В описанном варианте человеку всё равно, какую именно кошку кормить. Вдруг завтра появится вторая?
                                          Человеку даже не обязательно знать, какой корм и в какую кормушку насыпать. Вдруг завтра к двум кошкам добавится хомяк?
                                          Описанный выше код легко отработает все перечисленные ситуации. Надо лишь давать ему правильные внешние объекты кормёжки и кормушки.
                                            0
                                            Тут должна для полноценного моделирования быть протечка абстракции, как и описано — корм положен в кормушку, кошка позвана, не хватает только таймер следующего кормления перевести на четыре часа вперед. То что кошка не поела — сугубо кошкины проблемы.
                                            0
                                            Если бы была возможна такая реализация — то метод «кормить» в таком виде лишний. Фактически «Человек» ни чего не делает.
                                            • UFO just landed and posted this here
                                                0
                                                Дело в том, что в этом примере не используется ничего из объекта «Человек». То есть этот метод мог бы быть статическим в терминах С++. А в терминах «рефакторинга» — скорее всего класс «Человек» в данном случае «жадный» и метод может быть удалён (так как перемещать его в класс «Кошка» смысла нет — он уже там в виде «есть_из» ).
                                                • UFO just landed and posted this here
                                                    0

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

                                                    0

                                                    А почему жена обращается к человеку, а не к кошке?
                                                    Значит ли это, что метод "покормить кошку" есть только в объекте "Человек"?

                                                    • UFO just landed and posted this here
                                                        0

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

                                                        • UFO just landed and posted this here
                                                            0

                                                            Ооо, действительно да.

                                                        0

                                                        Ну, у Boston Dynamics может есть роботы с таким методом :)


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

                                                  +4

                                                  Разве


                                                  Условимся, что метод принадлежит тому, кто воздействует:
                                                  Кто_действует.Метод(Объект_воздействия);

                                                  не противоречит


                                                  И, наконец, Монстр_1.НанесёноПовреждение(сила_повреждения:Float)

                                                  ?


                                                  Последнее больше похоже на Измаил.СменаСобственника(Турки, Суворов).
                                                  Особенно с учётом


                                                  появился бы новый объект — ракета. Со своим методом Tick, обрабатывающим действия за один тик игрового времени

                                                  , из которого по предложенной логике следует, что надо Ракета.НанестиПовреждение(Монстр_1, сила_повреждения).

                                                    0

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


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

                                                    +4
                                                    Вводим новый объект «Акт кормления» и скармливаем ему (хе-хе) все три аргумента.
                                                    Или «СервисКормления», если мы пишем анемичную архитектуру.
                                                      –1
                                                      1) Ну, это же не действие, а регистрация изменения состояния. Ок, я готов признать, что у объекта Крепость имеется метод СменаСобственника — выполняющий изменение всех гербов и флагов, которые в ней представлены, правил приёма путешественников, должностных инструкций для гарнизона и сторожей, используемой валюты, рациона питания (при захвате крепости мусульманами, из меню столовой исчазают блюда, включающие свинину).

                                                      2) Нет. Если бы нанесение повреждений ракетой было в момент выстрела, создавать объект Ракета бы не потребовалось. Смысл именно в том, что создан объект Ракета, он обрабатывает Tick (перемещение за 1 тик игрового времени — если ракета не самонаводящаяся, то эта обработка выполнится стандартным методом родительского объекта), и Explosion — взорваться. И только в момент взрыва будет нанесено повреждение тем существам (включая и монстров и игроков), которые были рядом.
                                                        0
                                                        1) у кормушки есть метод «добавить еду»
                                                        2) человек имеет метод «покоромить кошку», он включает в себя вызов у кормушки метода выше, и сигнал «позвать кошку», типа кс-кс-кс, почему метод «покормить кошку» тут, потому что это человек решает кормить ее или нет
                                                        3) кошка регистрируется на этот сигнал, observers или как угодно, ну и вызывает свой метод «поесть», вызвав у кормушки метод «убавить еду»
                                                        Так можно обработать сколько угодно кошек
                                                          0
                                                          1) у кормушки есть метод «добавить еду»

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

                                                          Кормушка — это пластмассовая мисочка. Кормушка не имеет собственных методов, это глобальная переменная, либо запись в базе данных (смотря, что и как пишем). Это не объект.
                                                            +1
                                                            Секунду, кормушка это хранилище, и где оно реализовано (БД, в ОЗУ) — неважно, иметь дело с глобальными переменными я вам не рекомендую, кормушек может быть множество все-таки, если это запись в БД, то пожалуйста, метод «добавить еду» заменится либо SQL запросом напрямую, либо запросом через билдер (который тоже как бы объект), либо вызовом метода вашей модели (это то же самое что и мой способ, только с записью в БД)
                                                              –3
                                                              иметь дело с глобальными переменными я вам не рекомендую
                                                              Представьте, что вы пишете игру-бродилку — симулятор Гарри Поттера от первого лица, напоминаю что Гарри Поттер имел питомца — сову. Ваша игра не позволяет играть за класс в целом, только за Поттера. Очевидно, что его сова — это глобальная переменная.
                                                              кормушек может быть множество все-таки
                                                              Глобальные переменные могут быть массивом.

                                                              Я имел ввиду, что изменение объёма пищи в миске не стоит выделять в отдельный функционал.
                                                                +8
                                                                Очевидно, что его сова — это глобальная переменная.

                                                                Ну уж нет, не очевидно.

                                                                  +1
                                                                  Очевидно, что его сова — это глобальная переменная

                                                                  Нет, сова — самостоятельный объект со своими тасками.
                                                                    0
                                                                    Нет, сова — самостоятельный объект со своими тасками.
                                                                    Конечно. Как это противоречит тому что она глобальная переменная?
                                                                    И как обратиться к ней из кода программы?
                                                                      0
                                                                      Сова физически не присутствует одновременно везде глобально, она лишь может перемещаться глобально, как и сам Гарри Поттер, тоже способный перемещаться глобально.
                                                                        0
                                                                        Очевидно, сова не глобальна, она сейчас, скажем, летает вдоль перрона 9¾, в центре перрона, движется к последнему вагону со скоростью 4 метра в секунду. Не понял ваш аргумент. Сова должна быть описана как локальная переменная класса «железнодорожный перрон»? Зачем?

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

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

                                                                            В этом разница между Буклей и прочим животным миром.
                                                                              +2
                                                                              Тем, что существует в единственном экземпляре. Эту сову, принадлежащую Поттеру, зовут Букля. Вы не можете создать сцену, в которой их будет две.

                                                                              К глобальным переменным, внезапно, все это не имеет никакого отношения. Это обычный такой объект с идентичностью. Собственно, в каком-то смысле, любая доменная сущность (в смысле domain entity по DDD) — она такая же: существует в одном экземпляре, обладает continuity и так далее.

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

                                                                                Другой пример глобальной переменной — игровое время суток, игровой сезон года. Это простые переменные. Хогвартс и Букля — сложные, их структура читается из файлов конфигурации.
                                                                                  +1

                                                                                  Глобальная переменная не зависит от сеанса по определению. Программа запущена — глобальная переменная есть, даже если пользователь ещё не нажал "новая игра" или "загрузить игру".


                                                                                  Это если допустить, что программа чисто однопользовательский монолит.

                                                                                    –1
                                                                                    Я имел ввиду сеанс работы программы до её выключения.
                                                                                    Не сеанс юзера в ней.
                                                                                      +1

                                                                                      Зачем создавать Сову, до того как пользователь начал играть?

                                                                                        –1
                                                                                        Для элемента активной заставки например. Зачем создавать замок, если пользователь не начал играть в Unreal1?

                                                                                        Но ваш вопрос не имеет отношения к написанному мной: глобальная переменная просто есть. До того как пользователь зашёл в игру, и до того как сова появилась по сюжету, и после того как её убили из-за неаккуратных действий игрока, в ней может быть nil. Пусто. Но переменная-то есть.

                                                                                        В каком языке программирования вы пишете, что глобальные переменные в нём требуется «создавать» в рантайм?
                                                                                          +1

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


                                                                                          В каком языке программирования вы пишете, что глобальные переменные в нём требуется «создавать» в рантайм?

                                                                                          Это вы на каком-то странном языке пишете, в котором кроме глобальных переменных ничего нет.

                                                                                            +2
                                                                                            Но переменная-то есть.

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


                                                                                            В каком языке программирования вы пишете, что глобальные переменные в нём требуется «создавать» в рантайм?

                                                                                            Питон.


                                                                                            Python 3.6.8 |Anaconda, Inc.| (default, Feb 11 2019, 15:03:47) [MSC v.1915 64 bit (AMD64)] on win32
                                                                                            Type "help", "copyright", "credits" or "license" for more information.
                                                                                            >>> q
                                                                                            Traceback (most recent call last):   
                                                                                              File "<stdin>", line 1, in <module>
                                                                                            NameError: name 'q' is not defined   
                                                                                            >>> q = 3
                                                                                            >>> q
                                                                                            3
                                                                                              –1
                                                                                              Вот совершенно не понятно, зачем она «есть», особенно когда мы наконец выяснили, что объект, на который она ссылается, может как быть, так и не быть.
                                                                                              А затем, что «у меня нет совы» (переменная пуста) и «мне не известно что такое сова» (переменная отсутствует) — не одно и то же.
                                                                                                +2

                                                                                                А точно всему миру нужно знать, что такое сова?

                                                                                              0

                                                                                              На PHP и JS. В них просто не требуется создавать глобальных переменных. Можно, но не требуется. Более того, это считается плохим стилем по умолчанию. Чтобы ввести глобальную переменную, нужно очень серьёзно обосновать это обычно, и то не факт, что поможет.

                                                                                      • UFO just landed and posted this here
                                                                                          –1
                                                                                          Под глобальной переменной обычно понимают переменную с временем жизни — весь сеанс работы программы, и видимостью — везде. (Поскольку тут очень любят выискивать исключения, поясняю что видимость везде не отменяет действия по доступу к ней если того требует язык, как это сделано в PHP)
                                                                                            +1

                                                                                            Теперь осталось понять, зачем этой несчастной сове видимость везде и время жизни весь сеанс программы.

                                                                                              –1
                                                                                              Сове нужна видимость там где Поттер, а игра от его лица.
                                                                                                0

                                                                                                И что?

                                                                                                  +2

                                                                                                  Мне вот очень интересно: а что, Гарри правда всегда имеет связь со своей совой? Или это все-таки обычные отношения человека с питомцем (пусть и очень умным), и поэтому если улететь на другой континент, то, что сова перелетела из комнаты в комнату, ее владельцу не известно?

                                                                                                    –1
                                                                                                    >> lair Мне вот очень интересно: а что, Гарри правда всегда имеет связь со своей совой (...)

                                                                                                    Не всегда. Но сова — глобальная переменная.

                                                                                                    Это так же, как время суток. Глобальная переменная время суток имеет значение — сейчас день. А я в данный момент могу быть в лифте. И это может быть не тот лифт который в ТЦ Европейский возле м. Киевская в Москве, который снаружи здания, а самый обычный лифт. Я не контактирую в данный момент с природой напрямую. Но день остаётся днём.
                                                                                                      +1
                                                                                                      Но сова — глобальная переменная.

                                                                                                      Но почему?


                                                                                                      Это так же, как время суток.

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


                                                                                                      Глобальная переменная время суток имеет значение — сейчас день.

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


                                                                                                      Да, текущее время — это хороший пример "глобальной переменной". Но даже это иногда оказывается неудобно (я уже приводил пример с ITimeProvider). Но вот сова тут не при чем.


                                                                                                      Но день остаётся днём.

                                                                                                      … а вы, случайно, не путаете состояние с переменной?

                                                                                              • UFO just landed and posted this here
                                                                                                  +1

                                                                                                  Глобальная переменная — это про область видимости. Срок жизни может быть любым. Если вы считаете иначе, то стоит пересмотреть свое мнение.

                                                                                                    –3
                                                                                                    Молодец, пять.

                                                                                                    А теперь, давайте сделаем диалог менее философским. Напишите на любом языке программирования глобальную переменную с ограниченным сроком жизни. (Я могу, кстати. Drop Sequence в Оракле. Но это настолько редкий и вырожденный случай......)

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

                                                                                                      Питон.


                                                                                                      >>> q = 3
                                                                                                      >>> q
                                                                                                      3
                                                                                                      >>> del q
                                                                                                      >>> q
                                                                                                      Traceback (most recent call last):
                                                                                                        File "<stdin>", line 1, in <module>
                                                                                                      NameError: name 'q' is not defined
                                                                                                      • UFO just landed and posted this here
                                                                                                          0

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

                                                                                                            0

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

                                                                                                            0

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

                                                                                                              0
                                                                                                              >> ads83
                                                                                                              Мне неизвестно, как в Delphi прервать существование глобальной переменной до завершения работы программы. Можно освободить память, можно присвоить длину ноль динамическому массиву (присвоением nil), можно сделать экземпляру объекта Free или FreeAndNil, но удалить переменную в этом языке, как мне представляется, нельзя.

                                                                                                              Смысл, которого так можно добиться — а именно, когда переменная больше не нужна, то использовать ту же область памяти для хранения других данных другого типа — в Delphi реализовать можно, используя механизм record case of. Но развоплощения переменных в этом языке нет.
                                                                                                                0

                                                                                                                Видимо, я не понял как работает деструктор в Делфи. Мои ожидания


                                                                                                                1. память помечается как неиспользуемая и может быть занята другими данными
                                                                                                                2. обращение по указателю (все объекты — это указатели?) на эту область памяти приведет к ошибке.
                                                                                                                  Т.е. код вида


                                                                                                                  GlobalVar := TObject.Create;
                                                                                                                  LocalVar := GlobalVar; 
                                                                                                                  GlobalVar.Destroy; 
                                                                                                                  WriteLn(LocalVar);

                                                                                                                  вызовет ошибку.


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


                                                                                                                  0
                                                                                                                  Я дополню ваш код секцией var:
                                                                                                                  var GlobalVar,LocalVar:TObject;
                                                                                                                  begin
                                                                                                                  GlobalVar := TObject.Create;
                                                                                                                  LocalVar := GlobalVar; 
                                                                                                                  GlobalVar.Destroy;

                                                                                                                  Здесь, переменные GlobalVar и LocalVar работают как тип pointer. Они состоят из 4х байт (если выбрать 64х-битный режим компиляции, из 8 байт), а сама структура лежит в ОЗУ.

                                                                                                                  Вы создали две переменных, указывающих на одну и ту же область памяти. Затем, командой Destroy (если в самом деле будете писать на Delphi коммерческий продукт, никогда не используйте Destroy, используйте Free или FreeAndNil.) эту память освободили, а ссылка осталась.

                                                                                                                  Затем… я даже не понимаю что вы делаете. Строка
                                                                                                                  WriteLn(LocalVar);
                                                                                                                  ожидаемо, не компилируется, она не имеет смысла.

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

                                                                                                                  Представьте, что переменная это билет на поезд, в нём написано что вам надо сесть в вагон номер 10. Приехал поезд, а в нём только 7 вагонов. Продолжает ли существовать купленный вами билет? Да.
                                                                                                                    +1

                                                                                                                    Ну что же, я удовлетворен, что вы не спорите с тем что


                                                                                                                    в общем случае глобальность переменной — про область видимости, а не цикл жизни
                                                                                                                      0

                                                                                                                      Если мы говорим о глобальных переменных, то должны быть и локальные. Я дал вполне говорящие имена, но вы привели пример с глобальной переменной LocalVar :-) Я имел в виду что-то вида


                                                                                                                      var GlobalVar:TObject;
                                                                                                                      procedure SomeProcedure()
                                                                                                                        var LocalVar:TObject;
                                                                                                                      begin
                                                                                                                        GlobalVar := TObject.Create;
                                                                                                                        LocalVar := GlobalVar; 
                                                                                                                        {GlobalVar.Destroy;}

                                                                                                                      Возможно, я снова что-то упустил — моя цель продемонстрировать идею, а не написать компилирующийся код на языке, который не знаю изучал 20 лет назад. Идея же в том, что хотя у нас есть переменная, она ссылается в Неизведанное — даже не в null — и потому "померла".
                                                                                                                      Делфи вообще уникальна тем, что описание переменной синтаксически жестко разделено с ее инициализацией. Для меня было неожиданностью прочитать, что есть глобальная переменная модуля, которая не совсем глобальна.
                                                                                                                      Также странно для меня звучат слова (из той же ссылки и ваши), что Глобальные переменные создаются во время запуска приложения. В моем понимании цикл жизни переменной начинается с момента ее инициализации, т.е. присвоения ей значения (справа либо конструктор, либо другая переменная, либо выражение) и заканчивается деструктором (вызываемом явно или неявно).
                                                                                                                      Видимо, мое понимание отличается от идеологии Делфи, но справедливо для многих других языков.

                                                                                                                        +1
                                                                                                                        В моем понимании цикл жизни переменной начинается с момента ее инициализации

                                                                                                                        На самом деле — с момента выделения памяти. Вот чем эта память инициализирована — вопрос занятный, и в каждом языке свой.

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

                                                                                                                          Физически, переменные это области ОЗУ. Допустим, программа использует 200 переменных. Значит, машинный код внутри exe файла будет переменную номер 19 рассматривать как место в блоке ОЗУ, выделенном программе, начальный адрес которого равен размеру всех переменных с 1 по 18. (Там чуть сложнее, так как размер переменной компилятор часто дополняет до чуть большего ради роста скорости обработки).

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

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

                                                                                                                            Я надеюсь, вы сейчас про какие-то конкретные программы говорите, а не про все вообще?

                                                                                                                              0
                                                                                                                              «Говорит» — неудачный термин, так как код к этому моменту ещё не начал выполняться. Я говорю про exe файлы. В PHP, JavaScript, СУБД — не так.
                                                                                                                                0
                                                                                                                                «Говорит» — неудачный термин, так как код к этому моменту ещё не начал выполняться. Я говорю про exe файлы.

                                                                                                                                … про все exe-файлы? Потому что, насколько мне известно, .net работает не так. Да и вообще под Windows, говорят, запускающийся поток просто получает выделенный стек фиксированного размера (и у этого размера есть значение по умолчанию, которое никак не связано с тем, какие у вас переменные).


                                                                                                                                (собственно, в случае с .net даже не очень понятно, размер каких "переменных" надо сообщать Windows)

                                                                                                                                  0
                                                                                                                                  >> lair

                                                                                                                                  Допустим, что первая строка программы — такая: MyArray[12345]:=6.

                                                                                                                                  Объясните, как программа может начать выполняться до того, как под статический массив MyArray была выделена память?
                                                                                                                                    0
                                                                                                                                    Допустим, что первая строка программы — такая: MyArray[12345]:=6.

                                                                                                                                    Что такое "первая строка программы"? Программы на каком языке? В C# не может быть такой первой строки.

                                                                                                                              +1
                                                                                                                              Физически, переменные это области ОЗУ

                                                                                                                              Не факт. Это могут быть регистры.

                                                                                                                                0
                                                                                                                                >> Не факт. Это могут быть регистры.

                                                                                                                                Поскольку речь шла про выделение памяти переменных в момент запуска exe файла, можно было додумать, что речь идёт про глобальные. Глобальные переменные могут храниться только в ОЗУ. Есть исключение: delphi — реализация цикла for, в котором переменная хранится и в ОЗУ и в регистрах, а по завершению цикла delphi-программистам предписывается считать, что её значение неопределено.
                                                                                                                                  0

                                                                                                                                  Если этого не знаешь заранее, то додумать такое сложно. Особенно для "в момент запуска". То, что я помню из exe файлов — там память для "глобальных переменных" выделяется до запуска программы. ОС выделяет память, копирует туда данные из файла и только тогда запускает

                                                                                                                                    0
                                                                                                                                    по завершению цикла delphi-программистам предписывается считать, что её значение неопределено.

                                                                                                                                    Вот для меня состояние глобальной переменной "значение не определено" является синонимом "цикл жизни завершился". Если после этого мы присваиваем ей какое-то новое значение, начинается новый цикл жизни.
                                                                                                                                    Но это на мой дилетантский взгляд. Возможно, создатель какого-то языка считал иначе.

                                                                                                                                  0
                                                                                                                                  А вам не кажется, что для того, чтобы присвоить «ей» значение, сначала «она» должна уже существовать?

                                                                                                                                  Существование переменной можно трактовать по-разному. Я вижу минимум два варианта


                                                                                                                                  1. Переменная существует с момента, когда она объявлена. Код еще не выполняется, память под переменную не выделена, но переменная как GlobalVar уже существует (например, ей можно присвоить null). С этой точки зрения трудно объяснить, почему обращение существующей, но непроинициализированной переменной должно вызывать ошибку.
                                                                                                                                  2. Переменная существует с момента, когда для нее выделена память/ей присвоено значение. В этом случае объявленная GlobalVar2, но не используемая в коде не существует. У нее есть область видимости, но нет времени жизни.

                                                                                                                                  Вполне возможно, существуют и другие точки зрения.


                                                                                                                                  Выделение памяти в разных языках происходит в разные моменты времени. В managed (Java, C#) память выделяется VM в момент создания объекта, т.е. когда отрабатывает конструктор.
                                                                                                                                  В Си и Делфи все иначе. Как я понимаю, и там и там память не выделяется при объявлении переменной (ведь непонятно, сколько выделить для SomeVar: TObject — в будущем она может указывать и на объект без полей, и на мегабайтного монстра). Если это не так — скиньте ссылки, почитаю для развития.

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

                                                                                                                                    Ну вот в PHP, если ничего не путаю, разделяется переменная как имя в качестве ключа в "таблице" переменных, где значение — указатель на отдельную структуру данных zvalue. И вот этот указатель может быть null, и этот не PHP null, а C и какой-нибудь var_value->type выдаст ошибку типа NPE.

                                                                                                                                      0
                                                                                                                                      память под переменную не выделена, но переменная как GlobalVar уже существует (например, ей можно присвоить null).
                                                                                                                                      Вы путаете три разных понятия, которые не стоит путать.

                                                                                                                                      1) Переменная может быть указателем, ссылающимся на область ОЗУ, где хранятся данные. Тогда память (не под переменную!!! а под данные на которые она смотрит!!!) не выделена, и поэтому в переменной хранится nil (а не Null!!!).

                                                                                                                                      2) Переменная может допускать значение Null. Например, в Delphi это класс переменных variant, а в СУБД — все типы столбцов, которым не задан атрибут Not Null. В этом случае в переменной может храниться Null, как значение. В теории БД, Null должно означать: значение есть, но мы не знаем его. (Из за такой трактовки, условие Null=Null считается равным False.) В практике не так, например для строчных ORACLE переменных, Null — пустая строка.

                                                                                                                                      3) Переменная может ещё не существовать. Например, в ORACLE возникнет ошибка при чтении из Sequence, которой ещё не создано.
                                                                                                                                        0
                                                                                                                                        В теории БД, Null должно означать: значение есть, но мы не знаем его. (Из за такой трактовки, условие Null=Null считается равным False.)

                                                                                                                                        Как раз наоборот, в БД NULL это отсутствие любого значения. И именно поэтому (NULL=NULL) = FALSE. Значение отсутствует, поэтому оно не может быть ничему равно.

                                                                                                                                          0
                                                                                                                                          Ок, в википедии оба варианта: «поле, не содержащее никакого значения» и «неизвестность информации».

                                                                                                                                          Грубо говоря, допустим, есть 100 автомобилей и мы ходим вокруг запертой стоянки и переписываем их номера глядя через забор. Переписали номера 98 автомобилей, на одном автомибиле номеров нет, и один так поставлен что номеров увидеть нельзя. Значит, имеем: 98 значений, 1 Null в смысле описанном вами, 1 Null в смысле описанном мной.

                                                                                                                                          Можно ли сказать, что у Васи и Пети одинаковый цвет волос, если мы их никогда не видели, и фотографий нет? (мой вариант Null) — нельзя.

                                                                                                                                          Можно ли сказать, что у Васи и Пети одинаковый цвет волос, если вот они перед нами, и они оба лысые? (ваш вариант Null) — я бы сказал что да, поэтому в вашем случае Null=Null — истина.
                                                                                                                                            +1
                                                                                                                                            Значит, имеем: 98 значений, 1 Null в смысле описанном вами, 1 Null в смысле описанном мной.

                                                                                                                                            Это значит, что у вас плохо сделан тип данных, раз вы не можете отличить "номера нет" от "номера не видно".

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

                                                                                                                                              Меня больше всего интересует, какой из перечисленных разных смыслов вы придадите Null-у.
                                                                                                                                                0
                                                                                                                                                Меня больше всего интересует, какой из перечисленных разных смыслов вы придадите Null-у.

                                                                                                                                                Никакой.


                                                                                                                                                Добро пожаловать в мир типов-сумм:


                                                                                                                                                type CarNumber =
                                                                                                                                                  | Unknown
                                                                                                                                                  | Known of string
                                                                                                                                                  | None
                                                                                                                                                  –1

                                                                                                                                                  Навскидку, nullable свойство number. null — ничего не знаем про номер. Нормальный номер — инстанс класса Number. Отсутствие номера, пустой номер, неразборчивый номер, какие-то другие особые случаи — special case наследники этого класса или их общего предка AbstractNumber

                                                                                                                                                  • UFO just landed and posted this here
                                                                                                                                                  0

                                                                                                                                                  NULL означает отсутствие значения поля при сохранении данных. Оно не говорит, по какой причине оно отсустствует. Если вам надо это хранить, одного признака "NULL или не NULL" недостаточно.


                                                                                                                                                  Ваша формулировка "значение есть, но..." не подходит для случаев типа автомобиля без номеров, потому я и возразил.

                                                                                                                        +3
                                                                                                                        Внезапно, это глобальная переменная. То есть переменная, существующая в рамках одного сеанса работы одного пользователя, до того как он закрыл программу.

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


                                                                                                                        "Глобальная переменная" — это про область видимости. Что характерно, и русская, и английская здесь согласны.


                                                                                                                        А "переменная, существующая в рамках одного сеанса работы одного пользователя, до того как он закрыл программу" — это про жизненный цикл. Вот вам простейший пример такой переменной, которая при этом не глобальная (не вдаваясь в разницу между сроком жизни программы и сроком жизни сеанса пользователя в ней, которые тоже могут не совпадать):


                                                                                                                        class Program
                                                                                                                        {
                                                                                                                            static void Main(string[] args)
                                                                                                                            {
                                                                                                                                var iWantToLiveForever = true;
                                                                                                                                //forever...
                                                                                                                            }
                                                                                                                        }

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


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


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

                                                                                                                        Это пример того, что можно хранить в глобальной переменной, но даже это не всегда удобно (не зря же появляются абстракции типа ITimeProvider).

                                                                                                                      +2

                                                                                                                      Кстати в мире Гарри Поттера есть машина времени временные петли. Например, там было два Гарри Поттера — один наблюдал за другим.


                                                                                                                      Я не помню наблюдалось ли там две Совы но не помню также фундаментального ограничения на этот счёт.


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

                                                                                                                0

                                                                                                                Передавать по ссылке, например. Сам объект находится глобально в оперативной памяти, а на него есть локальные ссылки, которые представляют этот объект внутри конкретного класса или метода.

                                                                                                                  0

                                                                                                                  Она не глобальная переменная. Она, по идее, свойство либо объекта ГарриПоттер, либо объекта ИгровойМир.

                                                                                                                    +1
                                                                                                                    И сколько объектов ИгровойМир у вас в оперативной памяти есть? Один? И он глобальная переменная? И зачем вам эта прослойка в виде объекта «весь мир»?
                                                                                                                      0

                                                                                                                      Нет, он свойство объекта Игра, а игр столько сколько запустили пользователи

                                                                                                                        0
                                                                                                                        Один пользователь на одном компьютере/телефоне в одном приложении может одновременно играть в две игры? Или вы считаете что делать игру, в которой каждый играет за Гарри Поттера лично, сетевой — это хорошая идея?

                                                                                                                        ПОЖАЛУЙСТА НАПИШИТЕ ПРОГРАММНЫЙ КОД ТОГО ЧТО ВЫ ГОВОРИТЕ.
                                                                                                                          0
                                                                                                                          Или вы считаете что делать игру, в которой каждый играет за Гарри Поттера лично, сетевой — это хорошая идея?

                                                                                                                          Вы, похоже, в Death Stranding не играли.

                                                                                                                            0

                                                                                                                            А чем она плохая?

                                                                                                                              0
                                                                                                                              Тем что на одном факультете будут учиться 200 000 Гарри Поттеров.

                                                                                                                              Тогда надо рандомизировать персонажей и это будет другой проект.
                                                                                                                                0

                                                                                                                                Факультет — такая же часть ИгровогоМира.

                                                                                                                                  0
                                                                                                                                  И что???? На нём поэтому должны учиться 200 000 Гарри Поттеров??? Помимо того что в подобную игру никто не станет играть она не имеет отношение к канону игромира.
                                                                                                                                    0

                                                                                                                                    Если игра однопользовательская по геймплею, то у каждого пользователя свой ИгровойМир, у которого свой ГарриПоттер, Сова и Факультет. При том на игровом сервере может быть много ИгровыхМиров

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

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

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


                                                                                                                                        Так же для минимизации возможности читинга (например, интернет-казино)


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

                                                                                                                                          –1
                                                                                                                                          Рассмотрим сценарий:
                                                                                                                                          1) День. На сову пролилась чернильница.
                                                                                                                                          2) Вечер. Поттер ужинает. Рядом есть сова.
                                                                                                                                          3) Ночь. Поттер спит, и ему снится, что он бабочка. Рядом нет совы.
                                                                                                                                          4) Утро следующего дня. Поттер завтракает. Рядом есть сова.

                                                                                                                                          Если мы удалим сову в начале пункта 3 и создадим в начале пункта 4, то как при отрисовке совы мы узнаем, что на неё менее семи дней назад пролилась чернильница, и поэтому на ней есть синее пятнышко?
                                                                                                                                            +2
                                                                                                                                            Если мы удалим сову в начале пункта 3 и создадим в начале пункта 4,

                                                                                                                                            Вот только это никак не связано с доступом к сове из любого места программы. Удалять ее никто не предлагал.


                                                                                                                                            Update, решил развернуть:


                                                                                                                                            Будем честными, "сова" в программе — это просто область (или несколько областей) памяти (если мы не говорим о персистентности, а мы о ней явно не говорим пока). Эта область — это не переменная, это структура данных (или даже объект, если нам так удобнее). Чтобы получить информацию о состоянии совы (или поменять это состояние), нам нужен адрес этой области, или более абстрактно, ссылка на эту структуру. Вот эта ссылка и лежит в переменной.


                                                                                                                                            Так зачем этой переменной быть глобальной? На срок жизни совы (в разумной реализации) это все равно никак не повлияет.

                                                                                                                                              –2
                                                                                                                                              Затем, что если она будет локальной, то после выполнения процедуры в которой эта локальная переменная, её значение будет потеряно.

                                                                                                                                              Да вот вам пример, найдите ошибку в коде (не совсем Delphi, но смысл ясен):

                                                                                                                                              var ЯТусуюсь:boolean;
                                                                                                                                              
                                                                                                                                              Procedure ДавайДавай!;
                                                                                                                                              var ЯПьян?:boolean:=False;
                                                                                                                                              begin
                                                                                                                                                case Random(4) of
                                                                                                                                                1:Потанцевать;
                                                                                                                                                2:Поорать;
                                                                                                                                                3:begin
                                                                                                                                                     Выпивать;
                                                                                                                                                     ЯПьян:=True;
                                                                                                                                                   end;
                                                                                                                                                else Тусить;
                                                                                                                                                end;
                                                                                                                                                if Time>=23:30 then
                                                                                                                                                begin
                                                                                                                                                   ЯТусуюсь:=False;
                                                                                                                                                   if ЯПьян? then ЕхатьНаТаксиДомой
                                                                                                                                                   else ЕхатьНаСвоейМашинеДомой;
                                                                                                                                                end;
                                                                                                                                              end;
                                                                                                                                              
                                                                                                                                              Procedure Тусовка;
                                                                                                                                              begin
                                                                                                                                                ЯТусуюсь:=True;
                                                                                                                                                while ЯТусуюсь do
                                                                                                                                                   ДавайДавай!
                                                                                                                                              end;


                                                                                                                                              Ошибка в том, что ЯПьян? — локальная переменная. Должна быть глобальной.
                                                                                                                                                +1
                                                                                                                                                Затем, что если она будет локальной, то после выполнения процедуры в которой эта локальная переменная выполнилась, её значение будет потеряно.

                                                                                                                                                Ее "значение" — это всего лишь ссылка на область памяти. Что с того, что она потеряется? Или в известных вам языках программирования локальные переменные не могут ссылаться на объекты за пределами области видимости?


                                                                                                                                                Смотрите, как прекрасно работает все:


                                                                                                                                                void PetARandomOwl(Owl[] owls)
                                                                                                                                                {
                                                                                                                                                  var owl = ChooseRandomFrom(owls); //локальная переменная
                                                                                                                                                  if (owl.AllowsToBeCaught)
                                                                                                                                                    owl.Pet();
                                                                                                                                                }

                                                                                                                                                Локальная переменная owl прекратила свое существование вместе с закрывающей скобкой (а скорее всего и не было ее вообще никогда, компилятор все на стек положил). Однако объект, на который она ссылалась, никуда не делся, и его состояние, измененное в ходе вызова метода Pet, так и осталось измененным.


                                                                                                                                                Собственно, в C#, насколько я его знаю, вообще невозможны глобальные переменные. И ничего, живет как-то, не теряет состояние.

                                                                                                                                                  +2

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


                                                                                                                                                  А вот тот, как вы используете глобальную переменную ЯТусуюсь является отличным примером того, почему глобальные переменные — зло по умолчанию.

                                                                                                                                                    0
                                                                                                                                                    А вот тот, как вы используете глобальную переменную ЯТусуюсь является отличным примером того, почему глобальные переменные — зло по умолчанию.

                                                                                                                                                    … хотя ее прекрасно можно сделать возвращаемым результатом ДавайДавай.

                                                                                                                                                      0

                                                                                                                                                      Именно

                                                                                                                                                      –1
                                                                                                                                                      >> больше она нигде тут не используется

                                                                                                                                                      Вы видели только две процедуры. И даже если так, почему в будущем я не захочу узнать пьян я или нет, в другом месте кода?
                                                                                                                                                      +3
                                                                                                                                                      Ошибка в том, что ЯПьян? — локальная переменная. Должна быть глобальной.

                                                                                                                                                      Вот в том-то и дело, что нет. Достаточно сделать пьян и тусуюсь свойствами я, которое я и передавать в ДавайДавай. Здравствуй, ООП.

                                                                                                                                                        –2
                                                                                                                                                        Вот в том-то и дело, что нет. Достаточно сделать пьян и тусуюсь свойствами я, которое я и передавать в ДавайДавай. Здравствуй, ООП.

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

                                                                                                                                                        Так же рассуждаете вы. Разве красиво, чтобы были глобальные переменные — сова, ЯПьян?, и т.д.? Нет!!! Значит, это свойства глобального объекта Я. И при этом вас не смущает, что теперь, Я — это глобальная переменная…
                                                                                                                                                          +2
                                                                                                                                                          И при этом вас не смущает, что теперь, Я — это глобальная переменная…

                                                                                                                                                          Так в том-то и дело, что она не глобальная. Она локальная для Тусовка (там создается, там и умирает).


                                                                                                                                                          (я же вам приводил уже такой же пример с совами)


                                                                                                                                                          Собственно, речь же не о том, что можно сделать глобальной переменной (хотя вот в C# ничего нельзя). Речь о том, зачем что-то нужно делать глобальной переменной.

                                                                                                                                                            –1
                                                                                                                                                            Так в том-то и дело, что она [переменная «Я», со свойствами пьян(да/нет) и т.д.] не глобальная. Она локальная для Тусовка (там создается, там и умирает).

                                                                                                                                                            Правда? Подобная мысль была у Пелевина (Арлекин не существует за пределами карнавала).

                                                                                                                                                            А если в Procedure ДавайДавай! версии 2.0, помимо Я, реализуется взаимодействие с другими восхитительными объектами, то надо менять список параметров процедуры?
                                                                                                                                                              +3
                                                                                                                                                              Правда?

                                                                                                                                                              Да, правда. И дело тут не в философии, а в вашем коде.


                                                                                                                                                              (ну и information hiding, конечно)


                                                                                                                                                              Аналогично, выше:


                                                                                                                                                              Вы видели только две процедуры.

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


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

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

                                                                                                                                                                +2
                                                                                                                                                                А если в Procedure ДавайДавай! версии 2.0, помимо Я, реализуется взаимодействие с другими восхитительными объектами, то надо менять список параметров процедуры?

                                                                                                                                                                Конечно. Это позволяет явно отслеживать, от чего зависит ее поведение.


                                                                                                                                                                (ну то есть еще есть методы на сервисах и вбрасывание сервисов, но это запутает нашу дискуссию)

                                                                                                                                                                  +1

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

                                                                                                                                        0
                                                                                                                                        да, может. В одну игру играет пользователь сам, в другую играют юниттесты и тесты поведения.
                                                                                                                                –2


                                                                                                                                Я сделаль!

                                                                                                                                  –1
                                                                                                                                  Вы забыли главное:
                                                                                                                                  Сова должна быть описана как локальная переменная класса «железнодорожный перрон»
                                                                                                                                  habr.com/ru/post/511572/#comment_21863620
                                                                                                                                0
                                                                                                                                del
                                                                                                                                –1

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

                                                                                                                                  0

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

                                                                                                                                    0
                                                                                                                                    Нет большой разницы между ООП:

                                                                                                                                    Кормушка1.Isoverflow:boolean

                                                                                                                                    и не ООП:

                                                                                                                                    Кормушка_Isoverflow(@Кормушка1):boolean

                                                                                                                                    (Здесь, "@" — означает что передаётся указатель, а не структура).
                                                                                                                                      +1

                                                                                                                                      А почему вы считаете, что первое — это ООП, а второе — нет? Если читать только запись, то может быть строго наоборот. Что в деталях реализации заставляет вас утверждать иначе?

                                                                                                                                        0
                                                                                                                                        Что значит фраза «читать только запись» в данном контексте?
                                                                                                                                          0

                                                                                                                                          Она означает, что я прочитал код, который вы написали, и не понимаю, почему вы считаете, что что-то там ООП, а что — нет.

                                                                                                                                            –1
                                                                                                                                            ООП — классы создаются
                                                                                                                                            не ООП — классы не создаются

                                                                                                                                            Классы (в Delphi) — это type ...=class(...)
                                                                                                                                            Кроме классов визуальных форм, которые делает сама среда.
                                                                                                                                            Простите, что приземлил вашу высокую философию.
                                                                                                                                              +1
                                                                                                                                              ООП — классы создаются
                                                                                                                                              не ООП — классы не создаются

                                                                                                                                              Ээээ… то есть вы серьезно считаете, что ООП — это классы?

                                                                                                                                                0
                                                                                                                                                Объе́ктно-ориенти́рованное программи́рование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.
                                                                                                                                                Википедия
                                                                                                                                                  +2

                                                                                                                                                  Не читайте русскую википедию:


                                                                                                                                                  Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

                                                                                                                                                  Можете выяснить, что бывает ООП без классов. А если почитать Кея, то можно выяснить, что ООП вообще требует только… объектов и сообщений.

                                                                                                                                                    –2
                                                                                                                                                    lair, Я не читаю русскую википедию (равно как и английскую), я работаю с Legacy code который написан на ООП. Примерно таким:

                                                                                                                                                    procedure TOverridingPricesHolder.TParallelSearchOverrideContainerAction.TParallelSearcher.TSearchTask.TSPOWorker.DoGetSpoOverContainerCol;


                                                                                                                                                    Программисты Delphi меня поймут.

                                                                                                                                                    Вы в своих идеях про ООП похожи на теоретика коммунизма, который приехал в постреволюционный СССР. А под красивыми названиями совершенно другое делают (см. выше).
                                                                                                                                                      +2
                                                                                                                                                      Я не читаю русскую википедию (равно как и английскую)

                                                                                                                                                      Тогда зачем вы на нее ссылаетесь?


                                                                                                                                                      я работаю с Legacy code который написан на ООП

                                                                                                                                                      … и делаете вывод, что весь ООП такой же? Зря.


                                                                                                                                                      А под красивыми названиями совершенно другое делают

                                                                                                                                                      То, что "другие люди" под красивые названиями делают что угодно, совершенно не мешает мне делать под этими же названиями то, что я считаю нужным.

                                                                                                                                                        –2
                                                                                                                                                        Я «не читаю википедию» — в том же смысле, в каком водитель со стажем не читает повествование где в его машине педаль тормоза.
                                                                                                                                                0

                                                                                                                                                ООП — это подход к программированию, если хотите, способ.
                                                                                                                                                Я видел немало кода, написанного на ООП языке, с классами, но в процедурном стиле. Шаблонный пример — GodObject.Кормушка_Isoverflow(@Кормушка1):boolean
                                                                                                                                                И я сам писал в ООП стиле в системе, исповедующей функциональный подход — за счет чего решения получались кривыми и малопонятными даже мне.
                                                                                                                                                То есть если использовать инструмент (классы) как задумано, результат не гарантирован (выйдет не-ООП код).

                                                                                                                                          0

                                                                                                                                          Согласен, что нет большой разницы.
                                                                                                                                          В то же время, разница проявляется в том, кто отвечает за проверки. В ООП — объект кормушка, в процедурном — тот, кто хочет ее пополнить. Когда моделируемый мир состоит из нескольких сущностей, это непринципиально.
                                                                                                                                          В случае больших систем проверки if not Кормушка_Isoverflow(@Кормушка1) then пополнить_кормушку() оказываются в разных процедурах, ответственность за переполнение размывается. Это может привести к ошибкам, особенно при изменении бизнес-логики: придется смотреть где проверку изменять, и возможно пропустить какие-то пограничные случаи. То есть эта разница, небольшая, позволяет избегать ошибок — в больших системах.

                                                                                                                                    +3
                                                                                                                                    Вот именно с такого подхода и начинается переусложнение систем


                                                                                                                                    Неправильно составленное ТЗ ведёт к неправильному решению задачи.

                                                                                                                                    Метод Человек.НакормитьКошку предполагает следующую последовательность действий:
                                                                                                                                    1) Надеть на руки перчатки;
                                                                                                                                    2) Взять в левую руку кошку;
                                                                                                                                    3) Взять в правую руку ложку с едой;
                                                                                                                                    4) Предпринять попытку засунуть ложку в рот кошке;

                                                                                                                                    Скорость поглощения пищи зависит от отношения свойств Ложка.Вместимость/Кошка.УровеньСопротивления, время кормления зависит от отношения свойств объектов (Перчатки.Толщина*Человек.Упорство)/(Кошка.ДлинаКогтей*Кошка.УровеньСопротивления).

                                                                                                                                    Метод Человек.ДатьКормКошке предполагает уже совсем другие действия посредством взаимодействия с объектом Кормушка. При этом к объекту Кормушка может быть применён метод Destroy, если количество корма очень маленькое, а свойство объекта Кошка.Настроение имеет очень большую отрицательную величину.
                                                                                                                                      +2
                                                                                                                                      Кормушка — это пластмассовая мисочка. Кормушка не имеет собственных методов, это глобальная переменная, либо запись в базе данных (смотря, что и как пишем). Это не объект.

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

                                                                                                                                        +2
                                                                                                                                        Нет. Из текста очевидно что речь о миске, я решал конкретную задачу.
                                                                                                                                        Другие условия — это другая задача, имеющая другое решение.

                                                                                                                                        Та кормушка о которой вы говорите не требует участия человека для одного действия кормления кошки. С тем же успехом можно рассмотреть в качестве животного робота от Boston Dynamics. Другие условия — другие решения.
                                                                                                                                          0

                                                                                                                                          Тогда надо определить, что такое «покормить»:


                                                                                                                                          • насыпать корма в кормушку;
                                                                                                                                          • заставить кошку съесть корм из кормушки.

                                                                                                                                          В первом случае это метод объекта Человек, он устанавливает КоличествоКорма у объекта Кормушка. Во втором случае — приватная функция объекта Кошка, кошка внутри себя хранит ссылку на Кормушку и самостоятельно уменьшает\обнуляет переменную КоличествоКорма у Кормушки.


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

                                                                                                                                            0
                                                                                                                                            заставить кошку съесть корм из кормушки

                                                                                                                                            И как заставить съесть корм неголодную кошку?
                                                                                                                                              0

                                                                                                                                              Позвать более сильного конкурента, она сожрёт чтоб врагу не досталось. Проверено.

                                                                                                                                          0

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

                                                                                                                                          0
                                                                                                                                          del
                                                                                                                                            +1
                                                                                                                                            Кормушка — это пластмассовая мисочка. Кормушка не имеет собственных методов, это глобальная переменная, либо запись в базе данных (смотря, что и как пишем). Это не объект.

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


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

                                                                                                                                              0
                                                                                                                                              Замените задачу на Герой, Дракон и Волшебный меч
                                                                                                                                              • UFO just landed and posted this here
                                                                                                                                                  –2
                                                                                                                                                  кормушка — локация. она по определнию вместит весь корм, что находится в ней в неактивированном состоянии :)
                                                                                                                                              +6
                                                                                                                                              Вообще, на самом деле, изначальная «холиварная» затравка статьи довольно глупа, так как чрезмерно пытается упростить ситуацию, и из-за этого там что у ООПшного подхода проблемы, что у функционального.
                                                                                                                                              В реальности это взаимодействие двух black box систем — человека и кошки. Под «покормить» мы имеем в виду исполнение кошка.есть(<предложенная нами еда>), но этот метод относится к скрытой части реализации, и напрямую быть вызван не может — зато можно проверить, исполняется ли он или нет. Поэтому реализация, отличная от человек.покормитьКошку(человек.выбратьСтратегиюКормленияКошки(кошка), кошка) — заведомо будет обречена на провал. Кормушка тут и вовсе не нужна, это тривиальные внутренние детали реализации одной из возможных стратегий.

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

                                                                                                                                              А «уберите от меня это ужасное ООП» обычно происходит из-за бесконтрольного нарушения связности. Скажем, за отсутствием необходимости моделирования физики и вообще всего-всего — реализовали кормушку с методами «добавить еду» и «убавить еду» (как, собственно, оно и должно быть как максимум), а потом выяснилось, что кошка еду может и разбросать, и нужно срочно чинить расхождения — и какой-нибудь программист в мыле влепляет добавляет в кормушку private окружение: World, а спустя некоторое время кормушка у нас вдруг отращивает глаза, крылья, ноги, и сжирает кошку, человека, его дом, и вообще останавливает пространство и закукливает время через некорректное использование World. В ФП связность тоже можно внаглую сломать, кстати.
                                                                                                                                                +5
                                                                                                                                                Посмотрел в код своего кота, у него там так:
                                                                                                                                                У кормушки есть интерфейс добавить еду, чем человек и пользуется.
                                                                                                                                                А кот, он просто подписан на событие кормушки, отвечающее за то, что еда там обновилась.

                                                                                                                                                Дальше у кота вступает в дело какой-то сложный алгоритм на основании которого он решает, что же делать с этой едой, то ли мимо пройти, то ли всё же поесть.
                                                                                                                                                • UFO just landed and posted this here
                                                                                                                                                    0
                                                                                                                                                    Так было написано в цитате, но я тоже понял задачу как предоставить еду в миску. Мы программисты. В нашу работу входить додумывать ТЗ опираясь на здравый смысл.

                                                                                                                                                    Кстати, вы тоже поняли задачу как предоставить еду, при чем тут часы.
                                                                                                                                                    Никто не собирается именно «кормить» кошку.
                                                                                                                                                      +1
                                                                                                                                                      В нашу работу входить додумывать ТЗ опираясь на здравый смысл.

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

                                                                                                                                                    0
                                                                                                                                                    Кормушка — не активный объект и не может генерировать события. Кот самостоятельно пингует кормушку и проверяет изменение её состояния.
                                                                                                                                                    +10
                                                                                                                                                    С турками тоже не все ясно. Это у нас в России Суворов взял крепость Измаил. А в Турции некто паша именно про… л.
                                                                                                                                                      +1
                                                                                                                                                      А если человек уехал в отпуск, а кошечку кормить должен добрый сосед (соседка), у которого никогда не было опыта? Все эти отсылки к реальному миру только затуманивают абстракции.

                                                                                                                                                      Человек, уехавший в отпуск, оставляет инструкцию соседке — и она использует её. Назовем это стратегией.

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

                                                                                                                                                      Стратегии — это мощный паттерн, делайте их! Если язык поддерживает standalone-функции — их часто можно делать чистыми функциями.

                                                                                                                                                      Но повторюсь, вот такие рассуждения о человеке-кошке только затуманивают суть )
                                                                                                                                                        0

                                                                                                                                                        Человек покормил кошку, в монстра ударила ракета
                                                                                                                                                        … Сотрудник переходит в соседнее подразделение с изменением должности. Кто на ком стоял?

                                                                                                                                                          0

                                                                                                                                                          company.personnelDepartment.moveEmployee(employee, srcDepartment, dstDepartment, newPosition)

                                                                                                                                                            –1
                                                                                                                                                            Это элементарное транзакционные изменение свойств пачки объектов, ничего интересного — один из сервисов управления сотрудниками, и пачка событий в бухгалтерский сервис, сервис отчетов, офисный сервис, персонально вмем учатникам процесса, чтобы сохранить прозрачность изменений…
                                                                                                                                                            0
                                                                                                                                                            Если ві хотите кормить кошку через кормушку, и человек все єто делает — поздоровляю, у вас макароні.
                                                                                                                                                            Как правильно:
                                                                                                                                                            — Человек.FillUpCatsPlate
                                                                                                                                                            — Кошка.Update() {
                                                                                                                                                            if(хочу кушать) {
                                                                                                                                                            // найти полную кормушку и покушать из нее
                                                                                                                                                            }
                                                                                                                                                            }

                                                                                                                                                            Человек не может и не должен управлять кошкой.
                                                                                                                                                              0
                                                                                                                                                              Есть три объекта: кошка, кормушка и человек. Вам необходимо написать метод, который бы позволял человеку покормить кошку, воспользовавшись кормушкой.
                                                                                                                                                              Вопрос: методом какого класса будет являться метод.покормить()?

                                                                                                                                                              Постановки задачи не совсем понятная, кошка будет кушать кормушку? или кто то забыл про корм?
                                                                                                                                                              ну ок:
                                                                                                                                                              Человек.СделатьКормушкуСъедобной;
                                                                                                                                                              Кошка.КушатьИзКормушки;

                                                                                                                                                              Какого объекта этот метод? а четвертого объекта, который называется СистемаВЦелом.
                                                                                                                                                              СистемаВЦелом получает на вход всех этих Человек Кошка Кормушка и ими оперирует в соответствии с бизнес логикой.
                                                                                                                                                              DDD for ever. Человек думает понятиями, поэтому разработка в понятиях (объектах) это естественно и удобно для человеческого мышления.
                                                                                                                                                              Кто там что то имеет против ООП идёт на Ютуб смотреть видео Егора Бугаенко, его лекции об ООП, о том что самое главное в ООП это правильно создать объект — в конструктор надо передать все объекты нашей предметной области или фабрики что бы создать такие объекты в достаточном количестве.
                                                                                                                                                                0
                                                                                                                                                                Как ответить на данный вопрос?
                                                                                                                                                                Просто не нужно мучать кошку. У вас дома наверняка есть объекты под итерфейсом «дляНасыпания» и «можноНасыпать». Вот у вашего человека должен быть метод, который насыпает насыпаемые объекты в объеты в которые можно насыпать. Кормится или не кормится тем что насыпано, проблемы кошки, а не человека.
                                                                                                                                                                  +1
                                                                                                                                                                  1. Закон ома определяет не способ вычисления, например, силы тока через 2 оставшиеся, а взаимосвязь между величинами. Поэтому наличие 3 формул уместно.
                                                                                                                                                                  2. Стать хозяином Измаила не метод, а результат действия «победить в сражении».
                                                                                                                                                                  3. Действие происходит между человеком и пищей, человек перемещает пищу из холодильника в тарелку. Мотивация — это относится к бизнес логике, кормить кошку, кормить собаку, кормить себя.
                                                                                                                                                                  4. Вы напутали с интерфейсами. Выстрел — это часть интерфейса «стрелковое оружие». Для ножа говорить о выстреле, как и об оставшихся патронах неуместно.
                                                                                                                                                                  5. Чтобы что — то потрогать руками нужно, чтобы они у вас были, и объект, который вы собираетесь потрогать допускал это (попробуйте потрогать свет :)). Если эти 2 требования выполнены, то реализация операции «прикосновение» становится достаточно простым делом.
                                                                                                                                                                    –2
                                                                                                                                                                    В солнечный жаркий день, выйдете из тени на солнце. Поздравляю, вы потрогали свет.
                                                                                                                                                                      –1
                                                                                                                                                                      1. Определяет, потому, что закон физики это не только формула, но и смысл.
                                                                                                                                                                      2. В сражении по какому поводу? Может быть, всё таки по поводу завоевания крепости Измаил? То есть основная процедура — это получить Измаил, а сражение — основное действие для её реализации.
                                                                                                                                                                      3. И я о том же.
                                                                                                                                                                      4. И я о том же. Ок, не выстрел, а обобщённое Атаковать. Для ножа, действие по изменению состояния объекта в игре станет «измазан свежей кровью». Как я и писал, изменение состояния объекта программируется на уровне дочернего класса (нож и шотган — дочерние классы от TWeapon).
                                                                                                                                                                      5. Набирая сейчас это сообщение, я трогаю ноутбук. Чтобы полноценно описать это, нам потребуется использовать интерфейс, характерный для ноутбука.
                                                                                                                                                                      Если потребуется затем описать как я трогаю глину во время лепки, то это будет другой интерфейс, и другая терминология.
                                                                                                                                                                        +1
                                                                                                                                                                        закон физики это не только формула, но и смысл.

                                                                                                                                                                        И смысл закона Ома — взаимосвязь 3-х величин. Там нет "ведущей" величины и "ведомых", они все равноправные, и выбор величины слева от знака равенства определяется лишь тем, какая из них неизвестна.

                                                                                                                                                                          –1
                                                                                                                                                                          Электроплита греет сковородку, потому что на контакты плиты подано 220 вольт?
                                                                                                                                                                          Или на входе электроплиты образуется 220 вольт потому, что она греет сковородку?

                                                                                                                                                                          Вообще-то причина и следствие в этом вопросе довольно просто определяется.
                                                                                                                                                                            +2

                                                                                                                                                                            Это лишь потому, что вы знаете, что подано 220 в, это вам задано как начальное условие. Возьмите задачу, где задано, что через плиту протекает ток 2 ампера, известно её сопротивление, и нужно определить мощность. Величины напряжение там даже не возникнет: P = I^2*R. Если сопротивление меняется по длине, то на каждом участке будет выделяться своя мощность — значит сопротивление "главное"?


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

                                                                                                                                                                                0
                                                                                                                                                                                Пример не в тему. По ссылке статья о том как сковородка греет плиту.
                                                                                                                                                                                  0

                                                                                                                                                                                  А теперь прочитайте не по диагонали.

                                                                                                                                                                                    –1
                                                                                                                                                                                    Выработка электричества из тепловой энергии.

                                                                                                                                                                                    Вы испытываете необходимость в том чтобы спорить?
                                                                                                                                                                                    Я не могу вам помочь, я не психолог и не врач.
                                                                                                                                                                            0
                                                                                                                                                                            1. Смысл в том и есть, что вы неверно выделили объекты для реализации. Отсюда все противоречия. Если взять "источник питания" со свойством "напряжение", "нагрузку" со свойством "сопротивление" и объект "электрическая цепь", который будет содержать инстансы первых двух как свойства, то ваши 3 формулы станут методами последнего, и я не понимаю, что по вашему не так с ООП в данном случае.
                                                                                                                                                                            2. Сражение за Измаил часть более крупной системы под названием русско-турецкая война, где есть масса взаимодействующих объектов и условий. У вас возникло противоречие, потому что вы результат, в общем — то побочный, объявили главным, и кроме этого, вы его рассматриваете вне контекста системы. Битва за это место шла, потому что с него удобно атаковать неприятеля, или наоборот, защищаться. Здесь вообще могло не быть города.
                                                                                                                                                                            3. Здесь, наверное, был не прав, когда исключил кота из рассмотрения. Кот имеет свою реализацию важных методов "этоЕдаДляДанногоКота()", "требоватьЕдыОтХозяина()" и свойства "съедает за раз". Человек имеет свою реализацию метода "повестисьНаТребованияЭтойСкотины()". Миска вряд ли имеет важное значение и потребует реализации, главное, чтобы она была (ну или бог с ней, пусть будет). А вот корм скорее всего придется выделить ради хранения величины его запаса, только это будет не пакет, а корм как таковой. При желании можно пересчитывать в пакеты, килограммы, или миски. Естественно корм должен удовлетворять критерию "этоЕдаДляДанногоКота". Ну и нужен объект, который объединит все это в композицию, конечно, если вы не собрались прикармливать чужого кота, назовем этот объект "Семья". "Семья" корректно свяжет кота со своим хозяином и местом для хранения запаса кормов. Тогда реализация метода хозяина "покормитьСкотину()" станет простым перемещением количества корма в миску, в объеме который определяется потребностями питомца.
                                                                                                                                                                            4. Здесь прям не знаю что сказать. Для нужд игровой логики нужно хранить одни величины, например запас патронов, для нужд визуализации — другие, например, если вы в бою, то оружие может быть испачкано кровью. Что отнести к состоянию игрока, а что к его амуниции, наверное программисту виднее, вряд ли здесь все так уж однозначно можно расписать.
                                                                                                                                                                            5. Чтобы прикоснуться к предмету, он должен обладать поверхностью, ну или чем — то, что можно ею счесть (по этой причине, прикосновение к свету скорее всего невозможно, а прикосновение к воде можно принять с некоторыми оговорками). Раз уж мы собрались все трогать руками, они у нас должны быть. Прикосновение — это приведение расстояния между какой — то частью поверхности предмета и какой — то частью поверхности руки к нулю. Чтобы описать это, вам потребуется описать геометрическую форму руки и форму предмета. Какие нафиг интерфейсы!?!?
                                                                                                                                                                          0

                                                                                                                                                                          Поддержу ту точку зрения что нельзя отождествлять ООП с познанием или моделированием. Так и хочется сказать словами Гоголя, при чем тут турки. Нам будет плохо а не туркам.
                                                                                                                                                                          Но откуда взялась эта маркетинговая чушь я бы уточнил. Она исходит не из необходимости продвигать ООП языки а от расплодившихся в 90 гуру, которые закидали рынок книгами которые по объему раза в четыре превышают печально известный краткий курс истории КПСС в простонародье кирпич.
                                                                                                                                                                          Я принципы ООП к счастью изучал по вышедшей в начале 90 х книге Барбары Лисков Использование абстракций и спецификаций при разработке программ. Если сказать по простому то объект это данные и методы работы с данными. У нас есть простые типы. При помощи простых мы строим более сложные типы. И никакой философии.
                                                                                                                                                                          А кому все же философии нужно то рекомендую познакомиться с трудом Уемова Вещи, свойства, отношения. Там как раз об этом. И о инвариантности разных моделей тоже есть.

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