제이온

[Объекты] Глава 2. Объектно-ориентированное программирование

  • Язык написания: Корейский
  • Страна: Все страныcountry-flag
  • ИТ

Создано: 2024-04-28

Создано: 2024-04-28 13:46

Система бронирования кинобилетов


Рассмотрение требований

  • Мы хотим реализовать онлайн-систему бронирования кинобилетов.
  • Фильм представляет собой базовую информацию о фильме.
    • Название, время показа, информация о цене и т.д.
  • Показ представляет собой фактическое событие, когда зрители смотрят фильм.
    • Дата показа, время, номер сеанса и т.д.
  • Люди бронируют фильмы, но на самом деле правильнее сказать, что они бронируют конкретный сеансфильма.
  • Условия скидки
    • Наличие скидки на цену
    • Условие по порядку: определение наличия скидки с использованием номера сеанса
    • Условие по периоду: определение наличия скидки с использованием времени начала показа фильма
  • Политика скидок
    • Определение скидочной цены
    • Политика скидки в денежном выражении: скидка на определенную сумму от стоимости бронирования
    • Политика процентной скидки: скидка в процентах от полной цены
  • Для каждого фильма можно назначить одну политику скидок или не назначать вообще, а условия скидки можно комбинировать.
  • Если политика скидок применяется, но условия скидки не выполнены, или если политика скидок не применяется, то скидка не предоставляется.


На пути к объектно-ориентированному программированию

Взаимодействие, объекты, классы

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


Структура программы, соответствующая структуре предметной области

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

<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe7d22a03-4a24-40e9-8068-bd03b9fd816b%2FUntitled.png?table=block&id=3f1931fc-8ef9-470a-8189-3727146638f6&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/438;" width="2000" height="438"></span>

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


Реализация класса

  • Класс разделен на внутреннюю и внешнюю части, и для разработки качественного класса необходимо определить, какие части будут открыты снаружи, а какие скрыты.
    • Атрибуты объекта скрыты с помощью модификатора private, а необходимые для изменения внутреннего состояния методы открыты с помощью модификатора public.
  • Разделение внутреннего и внешнего пространства класса гарантирует автономность объекта, предоставляя программисту свободу реализации.


Автономные объекты

  • Объект должен быть автономным, обладать состоянием и поведением.
  • Объединение данных и функций внутри объекта называется инкапсуляцией.
  • Контроль доступа позволяет уменьшить внешнее вмешательство, что позволяет объекту самостоятельно принимать решения о своих действиях.
  • Принцип разделения интерфейса и реализации является одним из основных принципов, которым необходимо следовать при объектно-ориентированном программировании.
    • Публичный интерфейс: доступная внешним пользователям часть
    • Реализация: доступная только внутренней части


Свобода программиста

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


Сообщество взаимодействующих объектов

  • При представлении денег лучше обернуть их в объект, например, Money, вместо простого объявления переменной типа Long. Использование объектов позволяет лучше передавать смысл и обрабатывать повторяющиеся вычисления в одном месте.
  • Взаимодействие между объектами для реализации какой-либо функции системы называется взаимодействием.


Краткая история взаимодействия

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


Вычисление скидочной стоимости

Начало взаимодействия для расчета скидочной стоимости

  • В классе Movie нет подробной логики, связанной с политикой скидок, она делегирована интерфейсу DiscountPolicy. Использование наследования, полиморфизма и абстракции действительно важно.


Политика скидок и условия скидки

<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7b9b27a5-0dac-4ba7-9552-05b7f8fbdecd%2FUntitled.png?table=block&id=3264f189-6e12-4a55-94d2-75b851320c7a&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/535;" width="2000" height="535"></span>


Наследование и полиморфизм

Зависимость во время компиляции и во время выполнения

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


Программирование на основе различий

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


Наследование и интерфейсы

  • Наследование позволяет дочернему классу наследовать все интерфейсы, предоставляемые родительским классом.
  • Интерфейс определяет список сообщений, которые может понимать объект.
  • Movie отправляет DiscountPolicy сообщение calculateDiscountAmount. Movie не важно, экземпляр какого класса отвечает, главное, чтобы ответ был успешным.
  • Таким образом, как AmountDiscountPolicy, так и PercentDiscountPolicy могут взаимодействовать с Movie вместо DiscountPolicy.
  • Такое замещение дочернего класса родительским называется апкастингом (upcasting). Это связано с тем, что дочерний класс автоматически преобразуется в родительский класс.


Полиморфизм

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


Интерфейсы и полиморфизм

  • Если нет необходимости совместно использовать реализацию, а нужно совместно использовать только интерфейс, то вместо абстрактного класса можно использовать интерфейс.


Абстракция и гибкость

Сила абстракции

  • Преимущества абстракции
    • Если рассматривать только иерархию абстракции, то политику требований можно описать на высоком уровне.
    • Дизайн становится более гибким.


Гибкий дизайн

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


Компромисс между абстрактным классом и интерфейсом


  • В настоящее время NoneDiscountPolicy на самом деле не нужен, поскольку метод calculateDiscountAmount() класса DiscountPolicy возвращает 0, если нет условий скидки, поэтому проблем нет. Однако с точки зрения пользователя необходимо передать в Movie политику None, поэтому он был добавлен.
  • Поэтому класс NoneDiscountPolicy выглядит немного запутанно, и если изменить его следующим образом, то он станет более понятным.



  • Другими словами, мы абстрагируем DiscountPolicy как интерфейс и делим его на реализации — NoneDiscountPolicy и DefaultDiscountPolicy, которая представляет собой общую политику скидок.

<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F712983a9-3937-4265-82fe-66a144c44a0f%2FUntitled.png?table=block&id=f5ca651c-d03c-4a6c-97e9-7443ee5649a0&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/886;" width="2000" height="886"></span>

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


Повторное использование кода

  • Наследование можно использовать для повторного использования кода.
  • Однако для повторного использования кода лучше использовать композицию, чем наследование.
  • В текущем коде Movie использует код DiscountPolicy именно с помощью композиции.
  • Если мы возьмем Movie в качестве родительского класса и разделим его на AmountDiscountMovie и PercentDiscountMovie, то это будет использование наследования.


Наследование

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


Композиция

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


Источники

  • Объект

Комментарии0

[Для неспециалистов, выживание разработчика] 14. Краткое изложение часто задаваемых вопросов на техническом собеседовании для начинающих разработчиковМы обобщили и систематизировали часто задаваемые технические вопросы на собеседовании для начинающих разработчиков (области памяти, структуры данных, базы данных и т. д.). Надеемся, что это поможет вам подготовиться к собеседованию по разработке.
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

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

April 19, 2025

Ковариантность и контравариантностьВ этой статье объясняются понятия ковариантности и контравариантности. На примере Animal и Dog объясняется ковариантность и контравариантность, подчеркивается необходимость контравариантности для обеспечения гибкости, например, в обработке событий. Также
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

November 1, 2024

Возобновление сбора за билеты в кинотеатры: принят закон о поправкахВ парламенте принят закон о возобновлении 3%-ного сбора за билеты в кинотеатры. Эта мера направлена на пополнение фонда развития кинематографа и, как ожидается, будет способствовать оживлению киноиндустрии, однако вызывает опасения по поводу увеличения ра
issuessay
issuessay
issuessay
issuessay

February 27, 2025

Полное руководство: как получить скидку на фильмы с помощью налоговых баллов налоговой службыМы расскажем вам, как получить скидку в размере 2000 вон на фильмы в CGV с помощью налоговых баллов налоговой службы. Проверьте свои баллы в приложении Hometax или Sontax, получите купон CGV и используйте его. Возможны скидки и на другие культурные мероп
뉴스코리아
뉴스코리아
뉴스코리아
뉴스코리아

November 19, 2024