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

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
19-Июл-2020 12:30

Данная статья посвящена разбору вопроса о том, какому именно объекту ООП должен принадлежать метод, осуществляющий взаимодейстие между несколькими сущностями.
Это распространённая тема для холиваров. Например:
Не используйте ООП. Никогда. Это ошибка.
На эту тему есть много материалов, к примеру: 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», изменение состояние которого правильно опишет ожог руки. Огонь состояния не изменит.
Думаю, вы и сами можете продолжить список интерфейстов объектов, которые можно потрогать руками, с целью получения практики использования объектно-ориентированного программирования.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_analiz_i_proektirovanie_sistem (Анализ и проектирование систем), #_oop (ООП), #_programmirovanie (Программирование), #_proektirovanie_i_refaktoring (Проектирование и рефакторинг), #_oop (ооп), #_oop_golovnogo_mozga (ооп головного мозга), #_protsess_razrabotki (процесс разработки), #_protsedurnoe_programmirovanie (процедурное программирование), #_proektirovanie_sistem (проектирование систем), #_analiz_i_proektirovanie_sistem (
Анализ и проектирование систем
)
, #_oop (
ООП
)
, #_programmirovanie (
Программирование
)
, #_proektirovanie_i_refaktoring (
Проектирование и рефакторинг
)
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 23-Ноя 01:26
Часовой пояс: UTC + 5