«Точки зрения» в объектной модели - PullRequest
3 голосов
/ 22 января 2010

У нас есть два типа доменов: Пользователи и Локации .

У нас есть метод в LocationRepository : GetUserLocations () .

Существующая реализация:

var user = UserRepository.GetUser(userId);
var locations = LocationRepository.GetUserLocations(userId);

Для меня имеет больше смысла извлекать местоположения, связанные с пользователем, из Пользователь типа i.e.:

var user = UserRepository.GetUser(userId);
var locations = user.GetLocations();

Я думаю, что последняя реализация читается более чисто, и в качестве клиента API мне приходится иметь дело с меньшим количеством типов (то есть LocationRepository не требуется). С другой стороны, будет больше кода для поддержки, поскольку мне нужно записать «фасад» в LocationRepository .

Должен ли я действовать согласно своему инстинкту и создать фасад для Пользователь типа для LocationRepository , или я должен быть доволен статус-кво и жить с диаграммой последовательности, которая " мне кажется «неправильным» (т.е. поиск информации о местоположении кажется, что она извлекается с неправильной «точки зрения»)?

Ответы [ 2 ]

1 голос
/ 22 января 2010

Конечно, можно смоделировать наш материал примерно так:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

Может быть, экземпляры репозитория не должны быть видны «конечному разработчику» и быть инкапсулированы в модель.

Однако, поскольку у нас может не быть легкого доступа к Universe.Instance, нам нужна одна или несколько «точек входа», откуда можно фактически получить какие-либо данные.

UPDATE:

Я думаю, с одной стороны, целью должно быть как можно меньшее количество «точек входа в фасад хранилища», насколько это возможно, потому что это приближается к реальному миру, так как должен быть только один »Bing Bang «откуда все взято и что в конечном итоге породило все существующие данные ;-) ... Тем не менее, с другой стороны, конечно, сегодняшние системы - это всегда большие компромиссы, которые мы должны сделать, потому что способность моделировать реальный мир ограничена, есть последствия для производительности и так далее ...

Однако один из способов, которыми вы можете воспользоваться в вашем конкретном примере, - это использовать ваши репозитории для постоянного извлечения свежих данных, как в:

LocationRepository.Instance.GetUserLocations(userId);

... тогда как вы используете класс модели User для хранения результата в свойстве, например:

var locations = myUser.Locations;

Это свойство будет использовать технику отложенной загрузки для загрузки данных из LocationRepository по первому требованию, а затем для сохранения результата. Это говорит о том, что местоположения загружаются только один раз, что облегчает работу разработчиков, использующих вашу библиотеку. Затем вы можете решить, хотите ли вы сделать LocationRepository.GetUserLocation (userId) также видимым для конечного разработчика или нет. Имейте в виду, что при прохождении этого маршрута вам также потребуется создать некий неявный, а также явный механизм обновления и управления временем жизни.

Этот общий подход оказался очень полезным для меня. Однако асинхронный мир Silverlight et al теперь добавляет некоторые новые предостережения, поскольку такие свойства не могут быть обновлены мгновенно и синхронно с новым значением в одной строке кода. Когда мы запрашиваем обновление, мы теперь должны использовать методы привязки и / или использовать обратный вызов, чтобы затем иметь возможность дальнейшей обработки обновленного значения.

В целом, конечная цель, на мой взгляд, все еще состоит в том, чтобы, например, UserRepository был похож на другой обычный тип домена, очевидно, с обязанностью создавать новые единичные User экземпляры и добавлять их в хранилище пользователей. , а также предоставлять отфильтрованные представления (запросы) всем доступным пользователям. Было бы приемлемо, чтобы myUser.Locations и myLocations.ByUser["John Doe"] содержали ссылку на тот же результат. Это UserRepository может быть просто свойством другого класса, ответственного за его хранение, например, CompanyStaff. Продолжение этой идеи - вот что привело меня к этой Universe.Instance вещи. ; -)

1 голос
/ 22 января 2010

Я бы подошел к этому с точки зрения ремонтопригодности. Я согласен, что выполнение этого с фасадом в LocationRepository будет «правильным» и, вероятно, сделает код немного более читабельным.

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

...