DDD principlers и ASP.NET план проекта MVC

Поскольку у Вас есть неявный метод 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;
5
задан kaivalya 26 August 2009 в 23:32
поделиться

2 ответа

На мой взгляд, это одна из тех грязных вещей, которые всплывают в DDD.

В коде я рассматриваю совокупный корень как контейнер для любых «отношений» у него есть и любые объекты Entity, которые не могут существовать без корня Aggregate.

Например, возьмем пример Customer-> Order-> LineItem-> Product, который к настоящему времени забит до смерти. Совокупный корень, как я показал, в этом сценарии является клиентом. Тем не менее, вы не всегда хотите получать заказ через клиента. Возможно, вы захотите найти заказы на определенную дату.

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

Дело в том, что вы не хотите загружать клиента через заказ, но вы не обязательно хотите загрузите заказ через клиента.

Однако, начиная с заказа, вы вряд ли Я хочу просто получить LineItem, и вы, конечно, не собираетесь создавать их без заказа. С этой целью Order служит шлюзом к LineItems. LineItems не нужен собственный контроллер или репозиторий. Они существуют только внутри самого Ордена и, как таковые, являются частью Ордена (в этом случае Орден становится совокупным корнем) и управляются Сущностью Порядка.

Но LineItem, вероятно, будет иметь отношение к Продукт в системе. У продуктов будут свои собственные контроллеры, репозитории и т. Д., Потому что они могут существовать вне корня Aggregate.

Подводя итог моей бессвязной речи, я обычно смотрю на это так: если сущность может существовать сама по себе, у нее должен быть контроллер. Сущностями, которые не могут существовать сами по себе (в данном случае LineItems), следует управлять только их контейнером (совокупным корнем).

Поправьте меня какой-нибудь пурист из DDD, если / где я ошибаюсь?

Что касается второй части вашего вопроса, мне понадобятся некоторые дополнительные сведения о том, как вы представляете работу этих других сущностей. С учетом того, что вы здесь разместили, я могу представить, что PackagingOptions связаны с продуктом и будут частью совокупного корня Product. Теперь, имея в виду, что вы их редактируете, напрашивается вопрос: является ли это поисковой таблицей в системе или они являются одноразовыми значениями и поэтому должны рассматриваться как объекты значений?

3
ответ дан 15 December 2019 в 01:07
поделиться

Kaivalya,

Что касается вашего последнего комментария (stateless http):

Это зависит от контекста. Прежде чем перейти к деталям, я должен рассказать вам об основных принципах агрегатов:

Агрегаты определяют группу связанных объектов, которые должны рассматриваться как единое целое для целей изменения данных.

Это чрезвычайно важно. Цель наличия агрегатов - обеспечить соблюдение инвариантов. Например, у вас может быть политика типа "Заказ не может превышать 500 долларов". Тогда, чтобы обеспечить соблюдение этой политики, вы помещаете Order и OrderItem вместе в Order Aggregate. Таким образом, каждый раз, когда вы добавляете новый OrderItem, он должен быть добавлен через объект Order. Там же вы можете проверить общую цену и убедиться, что она не превышает $500. Если у вас в домене нет таких инвариантов, то нет смысла загружать все эти объекты вместе.

Теперь, возвращаясь к вашему комментарию:

Если у вас есть инварианты, которые должны соблюдаться, то можно загрузить всю совокупность, даже если это может иметь некоторые накладные расходы. Да, HTTP не имеет статусов, и вы загружаете весь агрегат только для того, чтобы изменить один из его дочерних объектов, а затем выбрасываете его. Это нормально. Самое важное здесь то, что вы выполняете свои инварианты. Именно для этого и существует DDD.

Цель DDD - охватить все бизнес-логики в вашем домене. Вы, безусловно, можете добиться лучшей производительности, если вам не придется загружать всю совокупность, но как вы обеспечите соблюдение инвариантов? Скорее всего, вам придется делать это в хранимой процедуре. Да, это работает, и это быстро, но работа с бизнес-логикой в хранимых процедурах во время обслуживания - это кошмар. Вот почему DDD развивался. Чтобы вы могли моделировать свои бизнес-требования с помощью объектно-ориентированных языков/инструментов, чтобы их было легче понять и модифицировать.

Просто помните, что DDD - это отличный подход, но не для всех типов проектов. Если вы имеете дело с проектом, в котором много бизнес-логики и высока вероятность того, что она изменится из-за характера бизнеса, то вам следует использовать DDD. Однако если ваш проект представляет собой скорее "прочитать что-то/записать что-то" без особой бизнес-логики, то использование DDD - это головная боль. Вы можете просто использовать LINQ to SQL (или SqlDataAdapters) и отправить ваши объекты в ваши представления. Вам даже не придется беспокоиться о поиске сущностей, объектов значений, агрегатов, хранилищ и т.д.

Надеюсь, это поможет,

Mosh

1
ответ дан 15 December 2019 в 01:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: