Коллекции и Одержимость Примитивными Типами. Окончание
Начало
Пользовательские классы коллекций
А что насчёт коллекций? Допустим, у нас есть следующий класс:
public class CustomerМожет коллекция должна быть представлена специальным классом, например:
{
public IReadOnlyList<Order> Orders { get; }
}
public class CustomerЭто зависит. Если в коллекции необходимо реализовать дополнительные бизнес-правила или инварианты, может быть хорошей идеей создать пользовательский класс. В противном случае оно того не стоит.
{
public OrderList Orders { get; }
}
Рассмотрим примеры выше.
1. Коллекция сущностей
public IReadOnlyList<Order> Orders { get; }
Какие бизнес-правила могут быть реализованы в этой коллекции? Допустим, не может быть повторяющихся заказов. Требует ли это введения нового класса? Нет. Чтобы соблюсти это бизнес-правило, все новые заказы должны проходить валидацию. Но нам не нужен для этого отдельный класс, эту ответственность может взять на себя сам класс Customer.Нам нужно, чтобы свойство
Orders не могло быть изменено напрямую, а это уже сделано путем представления этого свойства как IReadOnlyList. Значит нужно изменить класс Customer, добавив метод с необходимой проверкой:public class CustomerВ некотором роде
{
private List<Order> _orders;
public IReadOnlyList<Order> Orders => _orders;
public void AddOrder(Order order)
{
if (_orders.Contains(order))
throw new Exception();
_orders.Add(order);
}
}
Customer уже представляет собой пользовательский класс, инкапсулирующий коллекцию Orders.2. Пользовательский класс коллекции
Если коллекция не принадлежит никакой другой сущности, то имеет смысл создать для неё отдельный класс. Например, если вам нужно отслеживать всех пользователей, которые в данный момент находятся в сети, лучше всего представить их в виде пользовательского класса:
public class OnlineUsersЗдесь подразумевается, что, помимо собственно коллекции, необходимы некоторые дополнительные функции (например, описанный выше метод
{
private List<User> _users;
public void ForceLogOff(long userId)
{
// …
}
}
ForceLogOff), в противном случае класс OnlineUsers не нужен.Итого
Одержимость примитивными типами — это использование примитивных типов для моделирования предметной области.
Вам может понадобиться или не понадобиться отдельный класс для коллекции. Если коллекция представляет собой набор связанных сущностей, присоединённых к родительской сущности, то эта родительская сущность фактически действует как пользовательский класс. Отдельный класс для самой коллекции не нужен.
Если же коллекция является коллекцией корневого уровня, то для неё нужен пользовательский класс (при условии, что помимо самой коллекции необходимы дополнительные функции).
Источник: https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/