2010-09-16 4 views
0

Предположим, у меня есть классы домена:DDD наряду с коллекциями

public class Country 
{ 
    string name; 
    IList<Region> regions; 
} 

public class Region 
{ 
    string name; 
    IList<City> cities; 
} 

etc. 

И я хочу, чтобы эта модель в графическом интерфейсе в виде дерева.

public class Node<T> 
{ 
    T domainObject; 
    ObservableCollection<Node<T>> childNodes; 
} 

public class CountryNode : Node<Country> 
{} 

etc. 

Как я могу автоматически получать изменения в списке регионов для изменения списка городов, городов для региона и т. Д.?

Одно из решений заключается в реализации INotifyPropertyChanged на доменах и изменении IList <> ObservableCollection <>, но это кажется неправильным, потому что почему моя модель домена имеет возможность уведомлять изменения?

Другое решение заключается в том, чтобы эта ответственность возлагалась на уровень GUI/презентации, если какое-то действие привело к добавлению региона в страну, уровень представления должен добавить новую страну как к именам CountryNode.ChildNodes, так и к домену Country.Regions ,

Любые мысли об этом?

ответ

2

Rolling INotifyPropertyChanged в решении является частью реализации событий в вашей модели. По своей природе события сами по себе не соответствуют мантре DDD. Фактически, это одна из вещей, которые Эванс подразумевал, что отсутствовал в его раннем материале. Я точно не помню, где, но он упоминает об этом в этом видео; What I've learned about DDD since the book

Само по себе impelemnting eventing model на самом деле является законным в домене из-за того, что он вводит развязку между доменом и другим кодом в вашей системе. Все, что вы делаете, говорит о том, что ваш домен имеет возможность уведомлять заинтересованные стороны о том, что что-то изменилось. Таким образом, ответственность за это несет абонент. Я думаю, что, когда возникает путаница, вы используете только реализацию INotifyPropertyChanged для возврата к приемнику событий. Этот приемник уведомлений будет уведомлять подписчиков через зарегистрированный обратный вызов о том, что произошло «что-то».

Однако, с учетом сказанного, ваша ситуация является одним из сценариев «бахромы», в которых события не применяются так хорошо. Вы хотите посмотреть, нужно ли повторно заполнять пользовательский интерфейс при изменении самого списка. На работе текущее решение, которое мы используем ObservableCollection. Хотя он действительно работает, я не поклонник этого. С другой стороны, публикация факта, что один или несколько элементов в списке изменились, также проблематична. Например, как вы определяете энтропию списка, чтобы лучше определить, что он изменился?

Из-за этого я бы на самом деле считал, что это не является проблемой для домена. Я не думаю, что то, что вы описываете, было бы требованием владельца (ов) домена, а скорее артефактом архитектуры приложения. Если вы должны были запросить службы в домене после того, как будет сделано изменение, они вернутся правильно, и приложение все равно будет тем, что не соответствует шагу. В мире домена нет ничего действительно неправильного в этом моменте во времени.

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

Если у вас есть какой-то общий механизм кэширования, то естьраспределенный кеш, вы могли бы реализовать подход JIT-кэширования/выселения, в котором вставки и обновления лишали бы кеш-код (т. е. вытесняли кэшированные элементы), а последующий запрос загружал бы их обратно. Тогда вы могли бы поместить маркер в кеш который указывает на то, что было идентифицировано, когда этот предмет (ы) был/был перестроен. Например, если у вас есть элемент кэша, который содержит список идентификаторов для региона, вы можете сохранить DateTime, чтобы он был JIT-ed вместе с ним. Затем приложение может отслеживать версию JIT-ed, и только перезагружается, когда видит, что версия изменилась. Вам по-прежнему нужно опросить, но он устраняет эту ответственность в самом домене, и если вы просто проводите опрос для меньшего количества данных, это лучше, чем перестраивать всю вещь каждый раз.

Кроме того, перед переархивированием полномасштабного решения. Обратите внимание на проблему с владельцем домена. Это может быть совершенно приемлемо для него/нее, что у вас просто есть кнопка «Обновить» или пункт меню. Речь идет также о компромиссе, и я уверен, что большинство владельцев доменов предпочитают основные функции по определенным типам проблем.

2

О событиях - самый ценный материал, который я видел, исходит от Udi Dahan и Greg Young.

Хорошая реализация событий, которые я хочу попробовать, можно найти here.

Но начните с понимания, если это действительно необходимо, как предлагает Джозеф.

+0

Ваша текстовая ссылка, кажется, сломана. – jpierson

+2

@jpierson фиксированный. И я попробовал. Использование с успехом. –

Смежные вопросы