QR code

remove(42) vs. find(42).remove()

  • Translated by to

У нас есть список книг в объекте books. Как мы можем удалить одну книгу из него, зная ее идентификатор? Мы можем использовать books.removeById(42). В качестве альтернативы, мы можем найти ее с помощью books.findById(42) и затем вызвать b.remove(). Какой вариант предпочтительнее, и почему? Второй вариант лучше. Не только потому, что он более объектно-ориентированный, но также из-за нескольких практических преимуществ.

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

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

Если мы используем removeById(), мы должны декорировать объект books. Если мы используем remove(), мы можем декорировать отдельную книгу, полученную через findById(). Последний подход может быть более связанным, поскольку его декорируемый объект, вероятно, меньше и сосредоточен:

Handling Missing or Non-Deletable Books

Что, если книга не найдена или не может быть удалена? Подход removeById() не очень хорошо поддерживает шаблон Null Object. Он заставляет нас бросать исключение - или, что еще хуже, возвращать false, что противоречит принципу CQRS.

С другой стороны, возврат объекта, даже null или фиктивного объекта, предлагает более гибкое обработку ошибок. Например, мы можем безопасно получить доступ к title(), зная, что книга была успешно найдена - или перехватить и повторно вызвать исключения с более подробным контекстом:

Decoupling Retrieval and Deletion

Что, если извлечение и удаление объекта происходят в коде далеко друг от друга?

Если books знает, как найти, и book знает, как удалить, мы хорошо разделяем ответственности. Это также позволяет книге быть неизменяемой и инкапсулировать свой собственный идентификатор, уменьшая утечку внутренних данных:

Как только идентификатор обернут внутри книги с помощью findById(), он больше никогда не должен просочиться наружу. Это снижает количество обнаженных данных, к которым имеют доступ части кода, которым это не требуется.

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

Таким образом, использование findById(), за которым следует remove(), более полно принимает во внимание объектно-ориентированные принципы. Это позволяет более чистое расширение, лучшую обработку ошибок и более плотную инкапсуляцию.

Translated by ChatGPT gpt-3.5-turbo/42 on 2025-06-22 at 14:22

sixnines availability badge  GitHub stars