Проектирование ПО — главное, что интересует разработчиков, оно лежит в основе их умений. Это позволяет легко внедрить концепции безопасности через проектирование.
Страницу входа лучше вообще не упоминать: «Я, как пользователь, хочу, чтобы доступ ко всем моим загруженным изображениям был защищен с помощью аутентификации и чтобы изображения оставались конфиденциальными».
Безопасность требует к себе отдельного внимания
Чтобы обслуживание клиентов было на высоком уровне, управляющий отелем решил полностью возмещать стоимость бронирования, если отмена сделана в день прибытия до 16:00. Это обеспечивает высокую гибкость, но что, если кто-то специально забронирует номер и не явится? Не приведет ли это к тому, что номер окажется недоступным, в результате чего отель потеряет потенциальных клиентов? Несомненно, именно так и работает DoS-атака на предметную область. Эксплуатация правил отмены позволяет забронировать все номера и отменить бронь в самый последний момент без какой-либо оплаты. Таким образом злоумышленник может заблокировать номера определенного вида или направить клиентов в конкурирующий отель.
Такого рода атаки могут показаться выдуманными и маловероятными, но нечто подобное уже несколько раз происходило в реальности. Например, однажды компания-агрегатор такси, Lyft, обвинила своего конкурента, Uber, в попытке нанести финансовый ущерб путем заказа и отмены более 5000 поездок в Сан-Франциско99. Еще один случай произошел в Индии, где компания Uber подала в суд на своего конкурента, Ola, за заказ 400 000 ложных поездок100.
Защищать поля данных с помощью модификатора private и предоставлять сеттеры — это все равно что купить дорогую бронированную дверь и оставить ключ в замке.
При моделировании агрегата необходимо следовать строгим правилам, чтобы он работал как следует и выполнял поставленную перед ним задачу. Далее перечислены правила, предложенные Эриком Эвансом37.
• У каждого агрегата есть граница и корень.
• Роль корня играет одна конкретная сущность, размещенная внутри агрегата.
• Корень является единственным членом агрегата, на который могут ссылаться объекты за пределами границы. Поэтому:
• у корня есть глобальный идентификатор;
• корень управляет доступом к объектам внутри границы;
• все сущности, кроме корня, имеют локальные идентификаторы, которые могут быть неизвестны за пределами агрегата;
• корень может передавать другим объектам ссылки на внутренние сущности, но эти ссылки могут использоваться лишь временно, и их нельзя удерживать;
• корень может передавать другим объектам ссылки на объекты-значения.
• Инварианты между членами агрегата всегда соблюдаются в рамках каждой транзакции.
• Инварианты, охватывающие несколько агрегатов, не дают гарантии согласованности в любой момент, но в конечном счете они могут стать согласованными.
• Объекты внутри агрегата могут содержать ссылки на другие агрегаты.
То, как описывать концепцию — в виде объекта-значения без идентификатора или сущности с уникальным идентификатором, — зависит от контекста, с которым вы имеете дело.
Если вы моделируете такую предметную область, как центральный банк, то деньги, вероятно, стоит моделировать в виде сущностей. Дело в том, что с точки зрения центрального банка каждая пятидолларовая купюра уникальна, ведь он не только их печатает, но и следит за их оборотом и в конечном счете уничтожает. У каждой купюры есть уникальный серийный номер, который ее идентифицирует и позволяет отличить от любой другой. Она используется до тех пор, пока ее не изымут из оборота, например, чтобы заменить купюрой нового типа с новым идентификатором. С точки зрения центрального банка деньги уникальны и имеют жизненный цикл.
Атрибуты и аспекты поведения можно вынести из самой сущности и поместить их в отдельные объекты. Это могут быть другие сущности, но во многих случаях для этого применяются объекты-значения. Ключевые характеристики таких объектов перечислены далее:
• определяются не идентификатором, а своим значением;
• неизменяемые;
• должны составлять целостную концепцию;
• могут ссылаться на сущности;
• явно определяют и обеспечивают соблюдение важных ограничений;
• могут использоваться в качестве атрибутов в сущностях и других объектах-значениях;
• могут иметь короткое время жизни.
Сущности — это элементы модели, имеющие отчетливые свойства. Вот что делает их особенными.
• У сущности есть идентификатор, который ее определяет и отличает от других сущностей.
• Этот идентификатор не меняется на протяжении всего жизненного цикла сущности.
• Сущность содержит другие объекты, в том числе другие сущности или объекты-значения.
• Сущность отвечает за координацию операций с принадлежащими ей объектами.
Это означает следующее: чтобы узнать, совпадают ли две сущности, нужно проверять их идентификаторы, а не атрибуты. Именно идентификатор определяет сущность, какими бы ни были ее атрибуты. Идентификатор никогда не меняется. На протяжении своего жизненного цикла сущность может видоизменяться и приобретать много разных атрибутов и аспектов поведения, но ее идентификатор всегда остается прежним.