Сущности не должны иметь поведения. Они представляют данные, а сами данные пассивны.
В настоящее время я работаю над унаследованным проектом, включающим поведение в сущностях, и это ночной кошмар, код, который никто не хочет трогать.
Вы можете прочитать больше в моем блоге: Объектно-ориентированный анти-шаблон - объекты данных с поведением .
[Предварительный просмотр] Объектно-ориентированный анти-шаблон - объекты данных с поведением:
Атрибуты и поведение
Объекты состоят из атрибутов и поведения, но объекты данных по определению представляют только данные и, следовательно, могут иметь только атрибуты. Книги, фильмы, файлы, даже потоки ввода-вывода не имеют поведения. Книга имеет название, но не умеет читать. В фильме есть актеры, но он не знает, как играть. Файл имеет содержимое, но не знает, как его удалить. Поток имеет контент, но он не знает, как открыть / закрыть или остановить. Это все примеры объектов данных, которые имеют атрибуты, но не имеют поведения. Таким образом, они должны рассматриваться как тупые объекты данных, и мы, как разработчики программного обеспечения, не должны навязывать им поведение.
Обход данных вместо поведения
Объекты данных перемещаются по различным средам исполнения, но поведение должно быть инкапсулировано и обычно относится только к одной среде. В любом приложении данные передаются, анализируются, обрабатываются, сохраняются, извлекаются, сериализуются, десериализуются и т. Д. Например, объект обычно переходит от уровня гибернации к уровню обслуживания, к уровню внешнего интерфейса и обратно. В распределенной системе он может проходить через несколько каналов, очередей, кэшей и в конечном итоге попадать в новый контекст выполнения. Атрибуты могут применяться ко всем трем слоям, но определенное поведение, такое как сохранение, анализ, сериализация, имеет смысл только в отдельных слоях. Следовательно, добавление поведения к объектам данных нарушает принципы инкапсуляции, модульности и даже принципы безопасности.
Код написан так:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
может быть изменен следующим образом:
Book book = author.WriteBook();
printer.Print(book);
publisher.Publish(book);
customer.Buy(book);
reader = new BookReader();
reader.Open(Book);
reader.Read();
reader.Highlight();
reader.Bookmark();
librarian.GetRelatedBooks(book);
Какую разницу может принести естественное объектно-ориентированное моделирование! Мы прошли путь от одного монструозного класса Книги до шести отдельных классов, каждый из которых отвечал за свое индивидуальное поведение.
Это делает код:
- легче читать и понимать, потому что это более естественно
- проще для обновления, потому что функциональность содержится в меньших инкапсулированных классах
- более гибкий, потому что мы можем легко заменить один или несколько из шести отдельных классов переопределенными версиями.
- легче тестировать, потому что функциональность разделена, и легче имитировать