Поскольку у Вас есть неявный метод get и функции метода set, и Вы не можете изменить Результат функции, поскольку это - параметр константы.
(Примечание: В случае, если Вы преобразовываете запись в объект, результатом на самом деле был бы указатель, таким образом эквивалентный параметру var).
, Если Вы хотите остаться с Записью, необходимо использовать промежуточную переменную (или Полевую переменную) или использовать оператор WITH.
Посмотрите различные поведения в следующем коде с явным методом get и функциями метода set:
type
TRec = record
A: Integer;
B: string;
end;
TForm2 = class(TForm)
private
FRec : TRec;
FRec2: TRec;
procedure SetRec2(const Value: TRec);
function GetRec2: TRec;
public
procedure DoSomething(ARec: TRec);
property Rec: TRec read FRec write FRec;
property Rec2: TRec read GetRec2 write SetRec2;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
{ TForm2 }
procedure TForm2.DoSomething(ARec: TRec);
var
LocalRec: TRec;
begin
// copy in a local variable
LocalRec := Rec2;
LocalRec.A := Arec.A; // works
// try to modify the Result of a function (a const) => NOT ALLOWED
Rec2.A := Arec.A; // compiler refused!
with Rec do
A := ARec.A; // works with original property and with!
end;
function TForm2.GetRec2: TRec;
begin
Result:=FRec2;
end;
procedure TForm2.SetRec2(const Value: TRec);
begin
FRec2 := Value;
end;
На мой взгляд, это одна из тех грязных вещей, которые всплывают в DDD.
В коде я рассматриваю совокупный корень как контейнер для любых «отношений» у него есть и любые объекты Entity, которые не могут существовать без корня Aggregate.
Например, возьмем пример Customer-> Order-> LineItem-> Product, который к настоящему времени забит до смерти. Совокупный корень, как я показал, в этом сценарии является клиентом. Тем не менее, вы не всегда хотите получать заказ через клиента. Возможно, вы захотите найти заказы на определенную дату.
Если перевернуть его, у вас также не будет Клиента, у которого нет заказа. Эти двое находятся в некотором симбиотическом отношении, поэтому одно не является совокупным корнем другого.
Дело в том, что вы не хотите загружать клиента через заказ, но вы не обязательно хотите загрузите заказ через клиента.
Однако, начиная с заказа, вы вряд ли Я хочу просто получить LineItem, и вы, конечно, не собираетесь создавать их без заказа. С этой целью Order служит шлюзом к LineItems. LineItems не нужен собственный контроллер или репозиторий. Они существуют только внутри самого Ордена и, как таковые, являются частью Ордена (в этом случае Орден становится совокупным корнем) и управляются Сущностью Порядка.
Но LineItem, вероятно, будет иметь отношение к Продукт в системе. У продуктов будут свои собственные контроллеры, репозитории и т. Д., Потому что они могут существовать вне корня Aggregate.
Подводя итог моей бессвязной речи, я обычно смотрю на это так: если сущность может существовать сама по себе, у нее должен быть контроллер. Сущностями, которые не могут существовать сами по себе (в данном случае LineItems), следует управлять только их контейнером (совокупным корнем).
Поправьте меня какой-нибудь пурист из DDD, если / где я ошибаюсь?
Что касается второй части вашего вопроса, мне понадобятся некоторые дополнительные сведения о том, как вы представляете работу этих других сущностей. С учетом того, что вы здесь разместили, я могу представить, что PackagingOptions связаны с продуктом и будут частью совокупного корня Product. Теперь, имея в виду, что вы их редактируете, напрашивается вопрос: является ли это поисковой таблицей в системе или они являются одноразовыми значениями и поэтому должны рассматриваться как объекты значений?
Kaivalya,
Что касается вашего последнего комментария (stateless http):
Это зависит от контекста. Прежде чем перейти к деталям, я должен рассказать вам об основных принципах агрегатов:
Агрегаты определяют группу связанных объектов, которые должны рассматриваться как единое целое для целей изменения данных.
Это чрезвычайно важно. Цель наличия агрегатов - обеспечить соблюдение инвариантов. Например, у вас может быть политика типа "Заказ не может превышать 500 долларов". Тогда, чтобы обеспечить соблюдение этой политики, вы помещаете Order и OrderItem вместе в Order Aggregate. Таким образом, каждый раз, когда вы добавляете новый OrderItem, он должен быть добавлен через объект Order. Там же вы можете проверить общую цену и убедиться, что она не превышает $500. Если у вас в домене нет таких инвариантов, то нет смысла загружать все эти объекты вместе.
Теперь, возвращаясь к вашему комментарию:
Если у вас есть инварианты, которые должны соблюдаться, то можно загрузить всю совокупность, даже если это может иметь некоторые накладные расходы. Да, HTTP не имеет статусов, и вы загружаете весь агрегат только для того, чтобы изменить один из его дочерних объектов, а затем выбрасываете его. Это нормально. Самое важное здесь то, что вы выполняете свои инварианты. Именно для этого и существует DDD.
Цель DDD - охватить все бизнес-логики в вашем домене. Вы, безусловно, можете добиться лучшей производительности, если вам не придется загружать всю совокупность, но как вы обеспечите соблюдение инвариантов? Скорее всего, вам придется делать это в хранимой процедуре. Да, это работает, и это быстро, но работа с бизнес-логикой в хранимых процедурах во время обслуживания - это кошмар. Вот почему DDD развивался. Чтобы вы могли моделировать свои бизнес-требования с помощью объектно-ориентированных языков/инструментов, чтобы их было легче понять и модифицировать.
Просто помните, что DDD - это отличный подход, но не для всех типов проектов. Если вы имеете дело с проектом, в котором много бизнес-логики и высока вероятность того, что она изменится из-за характера бизнеса, то вам следует использовать DDD. Однако если ваш проект представляет собой скорее "прочитать что-то/записать что-то" без особой бизнес-логики, то использование DDD - это головная боль. Вы можете просто использовать LINQ to SQL (или SqlDataAdapters) и отправить ваши объекты в ваши представления. Вам даже не придется беспокоиться о поиске сущностей, объектов значений, агрегатов, хранилищ и т.д.
Надеюсь, это поможет,
Mosh