Я слышал много разных вводных статей об объектно-ориентированном программировании, но сегодня я прочитал одну из худших:

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

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

Обычно пример проясняет ситуацию, верно? Пример, который они приводят, таков:

Давайте создадим класс car. Он имеет свойство скорость и методы ускорения и печати.

Затем идет исходный код, объяснение синтаксиса, концепция наследования и концепция видимости.

Вы понимаете, почему я считаю это худшим первым примером объектно-ориентированного класса когда-либо?

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

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

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

Какой софт ускоряет машину? Встроенный код работает в каком-то компоненте автомобиля? Но зачем нужен класс для создания экземпляров несколько разных автомобилей? Это не так!

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

Как автор может привести пример, который больше сбивает с толку, чем помогает?

Ну, я не умею читать мысли. Но я помню стандартные фразы

ООП означает моделирование объектов из реального мира в программе.

и

Объекты в ООП инкапсулируют состояние и раскрывают поведение.

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

Имеет смысл?

У меня для вас плохие новости!

ООП используется в реальном программном обеспечении иначе.

Все подобные ООП-примеры животных и их звукового поведения, поведения студентов и их регистрации на занятия, банковских счетов и их поведения при расчете процентов… фейк!

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

Глупые контейнеры данных и бизнес-правила без сохранения состояния

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

Но в широкой области программного обеспечения для управления бизнесом/данными вы обычно найдете два разных типа классов:

Одним из типов является контейнер данных. Он имеет набор частных свойств и общедоступных методов доступа. Он имеет конструкторы и служебные функции, такие как toString(), hashCode() и equals() в Java. Но у него нет поведения!

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

Объекты передачи данных и объекты JPA являются такими контейнерами данных. Не начинайте реализовывать поведение в этих классах!

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

Бизнес-логика определяет, что делает программа, как она себя ведет. Реализация бизнес-логики означает определение того, что происходит с входными данными, как они обрабатываются, что вычисляется, как результат сохраняется или представляется. Классы контейнеров данных — это вход и выход для логики, а логика — это цель программного обеспечения.

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

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

Объектно-ориентированное программирование по книге просит вас объединить состояние и поведение в объекты.

Практика требует от вас четко отделить состояние от поведения.

Книга - обман.