Как избежать Анемичных Моделей предметной области и поддержать Разделение Проблем?

Вариант 1 кажется мне лучше, вероятно, потому, что я понятия не имел, как реально выполнить Вариант 2. Я бы порекомендовал это:

  1. построить DFA M1 такой, что L (M1) = ($ + b) a * (b + bba *) *
  2. построить DFA M2 так, чтобы L (M2) = b * (a + bb + bbb) b
  3. построить DFA M12 так, чтобы L (M12) = L (M1) \ L (M2)
  4. построить DFA M21 так, чтобы L (M21) = L (M2) \ L (M1) [ 119]
  5. регулярные выражения описывают один и тот же язык, если только L (M12) и L (M21) пусты

Чтобы узнать, принимает ли DFA M пустой язык, вы можете: [1121 ]

  1. построить M 'путем минимизации M
  2. посмотреть, принимает ли M' пустой язык, проверяя, является ли начальное состояние пустым и имеет ли все переходы, инициирующие в начальном состоянии, заканчивающиеся в начальном состоянии [ 1112]

Чтобы минимизировать DFA, вы можете начать с перечисления каждой пары состояний DFA. Затем вычеркните любую пару, где одно состояние в паре принимает, а другое - нет. Затем, итеративно, вычеркните любую пару (q, q '), где q переходит в некоторое состояние p на символе s, q' переходит в какое-то состояние p 'на символе s, а (q, q') уже вычеркнуто. Продолжайте до тех пор, пока больше не будут перечеркнуты пары состояний. В этот момент любые не вычеркнутые пары представляют эквивалентные состояния во входном автомате и могут быть объединены в минимальный автомат. Это всего лишь один метод. Другие методы доступны.

q    s    q'
q0   a    q1
q0   b    q2
q1   a    q1
q1   b    q3
q2   a    q2
q2   b    q3
q3   a    q3
q3   b    q0

Здесь, q0 является начальным и q3 принимает. Мы попробуем первый алгоритм:

    q0    q0    q0    q1    q1    q2
    q1    q2    q3    q2    q3    q3
#   --    --    --    --    --    --
1               XX          XX    XX   // q0,q1,q2 are not accepting; q3 is
2   XX    XX                           // on input b these go to q2,q3
3                                      // can't cross out q1,q2 by any rule

Мы находим, что q1 и q2 эквивалентны и могут быть объединены, чтобы дать следующий эквивалентный DFA:

q    s    q'
q0   a    q12
q0   b    q12
q12  a    q12
q12  b    q3
q3   a    q3
q3   b    q0

Способ построения автомата из регулярное выражение выглядит следующим образом:

  1. если r = x, где x - некоторая строка над алфавитом языка, то NFA для r можно построить, добавив одно начальное состояние и одно дополнительное состояние для каждого символ х; затем сделайте принятие последнего из этих состояний;
  2. если r = st, а M и M 'являются NFA для s и t, то NFA для r можно построить, изменив все принимающие состояния M на не -принятие при добавлении лямбда-переходов в ранее начальное состояние M ', которое больше не является начальным.
  3. Если r = s + t и M и M 'являются NFA для s и t, то NFA для r можно построить, добавив новое начальное состояние с лямбда-переходами к ранее начальным состояниям M и M', что больше не являются начальными;
  4. если r = s * и M является NFA для s, тогда NFA для r можно построить, добавив новое принимающее начальное состояние с лямбда-переходом к ранее начальному состоянию M, в то время как добавление лямбда-переходов из ранее принимающих состояний M в это новое начальное состояние.

Когда у вас есть NFA для регулярного выражения, вы можете определить его, используя конструкцию powerset или subset. Для этого создайте DFA, который имеет одно состояние для каждого подмножества набора состояний NFA. Затем добавьте переход из подмножества X в подмножество Y, если входной символ s переводит NFA из состояния x в состояние y, где x находится в X, а y находится в Y. Примечание. Сначала можно удалить лямбда-переходы, если это поможет вам Подумайте об этом или воспользуйтесь соглашением, что если s принимает NFA от q до q 'и имеет место лямбда-переход от q' к q '', то s также принимает NFA от q к q ''. Начальное состояние - это состояние, содержащее только начальное состояние NFA; все состояния, содержащие принимающее состояние, принимают.

Это поможет вам выполнить шаги 1 и 2. На этом этапе может быть полезно свести к минимуму согласно предложению, приведенному для шага 5. Затем, используйте конструкцию машины декартовых продуктов, чтобы найти DFA для различий (или просто построить один машина для симметричной разности и сохранения шага). Каждое состояние в продукте продукта будет соответствовать паре состояний, одно из которых берется из первого устройства ввода, а другое - из второго устройства ввода. Затем добавьте переходы в машине продукта, которые переводят DFA из состояния (x, y) в состояние (x ', y') везде, где одновременно происходят переходы от x к x 'на первой машине и от y к y' в вторая машина. Начальное состояние является тем, которое соответствует паре начальных состояний в машинах ввода; Принимающие состояния - это те, которые (для разности) имеют x принимающий и y не принимающий (для симметричной разности, это те, которые имеют либо x принимающий, либо y принимающий, но не оба).

20
задан Adam Ness 22 October 2008 в 23:01
поделиться

4 ответа

Действительно действительно хороший вопрос. Я провел довольно мало времени, думая о таких темах.

Вы демонстрируете большое понимание путем замечания силы между выразительной моделью предметной области и разделением проблем. Это во многом как сила в вопросе, который я спросил приблизительно Говорят, не Спрашивают и Единственный Принцип Ответственности .

Вот мое представление о теме.

модель предметной области А является анемичной, потому что она не содержит доменной логики. Другие объекты получают и устанавливают данные с помощью анемичного объекта области. То, что Вы описываете, не походит на доменную логику мне. Это могло бы быть, но обычно, справочные таблицы и другой технический язык наиболее вероятные условия, которые значат что-то для нас, но не обязательно чего-либо клиентам. Если это неправильно, разъяснитесь.

Так или иначе, конструкция и персистентность объектов области не должны содержаться в самих объектах области, потому что это не доменная логика.

Так для ответа на вопрос, нет, Вы не должны вводить целый набор недоменных объектов/понятий как справочные таблицы и другие детали инфраструктуры. Это - утечка одного беспокойства в другого. Шаблоны Фабрики и Репозитория от Управляемого Доменом Дизайна подходят лучше всего для хранения этих проблем кроме самой модели предметной области.

, Но примечание, что, если у Вас нет доменной логики, затем Вы закончите с анемичными объектами области, т.е. мешками глупых методов считывания и методов set, который является, как некоторые магазины утверждают, что сделали SOA / уровни служб .

Поэтому, как Вы получаете лучший из обоих миров? Как Вы фокусируете свои объекты области только доменная логика, при хранении UI, конструкции, персистентности, и т.д. из пути? Я рекомендую использовать технику как Двойная Отправка , или некоторая форма ограниченный доступ метода .

Вот пример Двойной Отправки. Скажите, что у Вас есть эта строка кода:

entity.saveIn(repository);

В Вашем вопросе, saveIn () имел бы все виды знания о слое данных. Используя Двойную Отправку, saveIn () делает это:

repository.saveEntity(this.foo, this.bar, this.baz);

И saveEntity () метод репозитория имеет все знание того, как сохранить в слое данных, как это должно.

В дополнение к этой установке, Вы могли иметь:

repository.save(entity);

, который просто звонит

entity.saveIn(this);

, я перечитал это, и я замечаю, что объект является все еще тонким, потому что он просто отправляет свою персистентность репозиторию. Но в этом случае, объект, как предполагается, является тонким, потому что Вы не описали никакую другую доменную логику. В этой ситуации Вы могли сказать "винт Двойная Отправка, дать мне средства доступа".

И да, Вы могли, но IMO, которые это выставляет, слишком многое как Ваш объект реализован, и те средства доступа, являются отвлекающими факторами от доменной логики. Я думаю единственный класс, который должен иметь, добирается, и наборы класс, имя которого заканчивается в "Средстве доступа".

я скоро оберну это. Лично, я не пишу свои объекты с saveIn () методы, потому что я думаю, даже просто имея saveIn (), метод имеет тенденцию замусорить объект области отвлекающими факторами. Я использую или друга шаблон класса, частный на пакет доступ, или возможно шаблон Разработчика .

хорошо, я сделан. Как я сказал, я был зациклен на этой теме вполне немного.

19
ответ дан 30 November 2019 в 01:08
поделиться

Попробуйте "шаблон репозитория" и "Домен управляемый дизайн". DDD предлагает определить определенные объекты как Совокупные корни других объектов. Каждый Агрегат инкапсулируется. Объекты являются "неосведомленной персистентностью". Весь связанный с персистентностью код помещается в объект репозитария, который управляет Доступом к данным для объекта. Таким образом, Вы не должны смешивать связанный с персистентностью код со своей бизнес-логикой. Если Вы интересуетесь DDD, проверяете eric evans книга.

0
ответ дан 30 November 2019 в 01:08
поделиться

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

ORM - то, что Вы делаете, когда Вы не хотите писать уровень служб.

, Когда Вы работаете с ORM, Вы все еще знаете о том, что навигация может включать запрос, но Вы не останавливаетесь на ней.

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

Однако, если существует более полная объектная модель, мы имеем в первом классе вещи вместо этих вырожденных справочных значений.

, Например, у меня есть некоторые деловые сделки, которые имеют один из n различные "тарифные планы" - своего рода модель ценообразования. Прямо сейчас реляционная база данных прежней версии имеет тарифный план как справочную таблицу с кодом, некоторыми числами оценки и (иногда) описанием.

[Все знают коды - коды священны. Никто не уверен, каковы надлежащие описания должны быть. Но они знают коды.]

, Но действительно, "тарифный план" является объектом, который связан с контрактом; тарифный план имеет метод, который вычисляет окончательную цену. Когда приложение спрашивает контракт за цену, контракт делегирует часть работы оценки к связанному объекту тарифного плана.

, возможно, был некоторый запрос базы данных, переходящий к поиску тарифный план при создании договорной цены, но это - случайный факт делегации ответственности между этими двумя классами.

1
ответ дан 30 November 2019 в 01:08
поделиться

Я согласен с DeadBeef - в этом и заключается напряжение. Я действительно не понимаю, насколько модель предметной области «анемична» просто потому, что она не спасает себя.

В ней должно быть гораздо больше. т.е. Это анемично, потому что служба выполняет все бизнес-правила, а не объект домена.

Service(IRepository) injected

Save(){

DomainEntity.DoSomething();
Repository.Save(DomainEntity);

}

'Do Something' is the business logic of the domain entity.

**This would be anemic**:
Service(IRepository) injected

Save(){

if(DomainEntity.IsSomething)
  DomainEntity.SetItProperty();
Repository.Save(DomainEntity);

}

Видите разницу наследования? Я знаю :)

1
ответ дан 30 November 2019 в 01:08
поделиться
Другие вопросы по тегам:

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