Я пытаюсь выяснить, как смоделировать иерархию типов значений в коде. Есть немало примеров и упоминаний об этом, и это немного упоминается в Верноне (Красная книга, глава 12, Репозитории).
Итак, допустим, у меня есть и порядок с линиями. Строки заказываются, и в Заказе указывается, как будет выбран заказ. Порядок может быть изменен вручную и системой для оптимизации вещей.
// Aggregate
public class Order
{
public OrderId Id { get; set; }
private List<OrderItem> _items { get; set; }
// Always ordered by requirement.
public IEnumerable<OrderItem> Items
{
get { return _items.
OrderBy(x => x.Order).
AsEnumerable(); }
}
}
Элементы хранятся в отдельной таблице, и все значения встроены (не важно, но полезно знать).
"CREATE TABLE IF NOT EXISTS `OrderLine` (
`id` int(10) NOT NULL auto_increment,
`orderitemid` numeric(9,2),
`order` varchar(255),
`orderitemtype` varchar(255),
`orderitemprogress` varchar(255),
`isonhold` numeric(9,2),
`width` numeric(9,2),
`height` numeric(9,2),
`isStackable` numeric(9,2),
`maxOnPallet` numeric(9,2),
`isfragile` numeric(9,2),
PRIMARY KEY( `id` )
);"
Из кода это выглядит так:
// How order sees an item.
public class OrderItem
{
public OrderItemId Id { get; set; }
// Common for all types.
public Order Order { get; set; }
public OrderItemType ItemType { get; set; }
public OrderItemProgress Progress { get; set; }
public int IsOnHold { get; set; }
// etc...
// Type specific, only one is set, other is null.
public ItemOfCatOne ProdOne { get; set; }
public ItemOfCatTwo ProdTwo { get; set; }
}
Теперь тип элемента (например, отдел) определяет, как система видит элемент и доменную логи c. Как и в случае, если строка отсутствует, ее следует переместить в следующий заказ или удалить из заказа, или заказ не должен начинаться, в зависимости от отдела.
Есть некоторые общие свойства для всех элементов, но есть определенные c, а также свойства могут использоваться несколькими элементами. OrderItemType
определяет, какое значение следует использовать, ItemOfCatOne
или ItemOfCatTwo
.
// Specific product with local identity own logic.
public class ItemOfCatOne
{
public OrderItemId Id { get; set; }
// Common for all types.
public Order Order { get; set; }
public OrderItemType ItemType { get; set; }
public OrderItemProgress Progress { get; set; }
public int IsOnHold { get; set; }
// Here are custom properties that may be common with other types or not.
public int Width { get; set; }
public int Height { get; set; }
public bool IsStackable { get; set; }
}
// Specific product with local identity and own logic.
public class ItemOfCatTwo
{
public OrderItemId Id { get; set; }
// Common for all types.
public Order Order { get; set; }
public OrderItemType ItemType { get; set; }
public OrderItemProgress Progress { get; set; }
public int IsOnHold { get; set; }
// Here are custom properties that may be common with other types or not.
public int Width { get; set; }
public int Height { get; set; }
public int MaxOnPallet { get; set; }
public bool IsFragile { get; set; }
}
Вопрос о OrderItem
...
С точки зрения Order
, нет типов Item, так что это означает, что бит IF-THEN-ELSE должен считывать и записывать в значение спецификации c.
Но, с точки или OrderItem
, нет элементы, потому что вы можете редактировать только ItemOfCatOne
или ItemOfCatTwo
, и тогда он должен иметь все общие свойства, включая OrderItemId
(локальный идентификатор?). Но редактирование общих значений должно быть отражено в OrderItem
. Это производит еще больше кода IF-THEN-ELSE. Не говоря уже о том, что каждый потребитель должен делать то же самое.
Q1: во многих отношениях это плохо, есть ли какой-нибудь общий способ справиться с этим?
Q2: моделирую ли я Order
неправильно? Должен ли я моделировать его с помощью третьего объекта значения и перенести туда все общие значения?