У меня возникли проблемы с поиском правильного решения следующей проблемы архитектуры.
В нашей настройке (набросок ниже) у нас есть 2 источника данных, где источник данных A является основным источником для элементов типа Foo. Существует вторичный источник данных, который можно использовать для получения дополнительной информации о Foo; Однако эта информация не всегда существует.
Кроме того, источник данных A может быть использован для извлечения элементов типа Bar. Тем не менее, каждый бар относится к Foo. Трудность заключается в том, что каждый столбец должен ссылаться на Foo, который, если имеется, также содержит информацию, дополненную источником данных B.
Мой вопрос: как устранить тесную связь между SubsystemA.1 и DataSourceB?
architecture
fstuijt
источник
источник
DataSourceA
иDataSourceB
уже развязаны?DataSourceA
зависит как от, такSubSystemA.1
и отSubSystemA.2
, но не отDataSourceB
.SubsystemA.1
чтобы использовать что-то другоеDataSourceB
,DataSourceA
не будет знать.DataSourceA
только заботы, уSubsystemA.1
которых естьgetFoo(id)
метод. Есть абстракция междуDataSourceA
иDataSourceB
.Ответы:
Я создал приложение с почти такой же архитектурой данных; у нас есть локальная база данных SQL, содержащая большую часть автоматизированной и внутренней оперативной информации, а затем стороннюю облачную службу, используемую для продаж, управления учетными записями, полевого персонала и т. д. Служба поддержки нуждалась в информации как физических лиц, так и клиентов. и оборудование, и получал его из двух разных приложений, пока я не вмешался.
Длинным и коротким является то, что один источник данных должен иметь ссылку на записи другого. В нашем случае сторонние облачные данные содержат ссылки на локальные данные, потому что это механизм, который мы контролировали больше всего. Теперь, с помощью идентификатора для записи из любого источника данных, мы можем получить данные из обоих; с помощью идентификатора облака мы извлекаем запись из облака, получаем идентификатор на месте и извлекаем данные на месте. Используя локальный идентификатор, мы опрашиваем оба источника данных на основе этого идентификатора.
В моей системе я не делал ни одного объекта дочерним по отношению к другому на уровне домена; любое использование данных из обоих хранилищ должно поддерживать два экземпляра объекта. Ни один из них не гарантированно существует, поэтому я так и сделал; приложение может работать только с облачными данными, с локальными данными или с обоими, с большими ограничениями, чем меньше данных.
Однако это не сложно изменить, особенно если вы уверены, что одна сторона будет существовать всегда; просто включите в объект свойство, представляющее сторону, для которой всегда будут существовать данные, то есть тип объекта, представляющий запись другого хранилища данных. Возможно более сложное «объединение» двух графиков в один.
Такая договоренность обязательно должна быть связана на каком-то уровне. У вас может быть DAL, который может взаимодействовать с обоими хранилищами данных, или вы можете сегментировать DAL, по одному на хранилище данных, и иметь более высокий уровень, такой как Контроллер, который получает данные из каждого и связывает их вместе. Но на каком-то уровне ваша программа должна обладать умом объединять данные этих двух разнородных источников данных.
Вы можете уменьшить требуемую связь в большинстве случаев, абстрагировавшись от подробностей, откуда именно поступают данные. Если вы получаете данные из веб-службы, которая предоставляется вам в качестве экземпляров сгенерированных классов, то установите конвертер для создания глубокой копии класса службы в то, что вы контролируете, которое не нужно будет менять, если данные источник делает (только если схема делает).
Теперь это может быть огромным предприятием; Облако, которое мы используем, имеет десятки классов доменов, некоторые из которых имеют сотни полей данных, и - вот что примечательно - вам может быть очень легко внести большие изменения в абстрактный тип данных, чтобы приспособиться к переходу в другое облако или другое удаленное источник данных. По этой причине я не беспокоился; Я использую сгенерированный домен веб-службы напрямую, и теперь, когда переход от облака к внешнему (но под нашим контролем) хранилищу данных вырисовывается, подробности которого я до сих пор не знаю, я просто планирую изменить формы и кодовые привязки приложения, в котором данные «объединяются», чтобы отразить новую схему и / или объекты данных. Это большая работа, независимо от того, как ты ее нарезаешь.
источник
Одним из способов решения этой проблемы является создание агрегированного источника данных, который содержит данные из обоих источников данных в одном месте. Задание будет периодически запускаться для проверки изменений в источниках
A
иB
и записи «дельт» в ваш агрегированный источник данных. Это позволит преобразовать два тесно связанных источника данных в единый связный источник данных.Несколько вещей могут помешать вам принять этот подход:
A
иB
должна быть сделана, удваивая требования к пространству.источник
DataSourceA
иDataSourceB
уже развязаны?DataSourceA
зависит как от, такSubSystemA.1
и отSubSystemA.2
, но не отDataSourceB
.Кажется, что на верхнем уровне есть два типа: Foo и Bar, и у вас есть только два действия верхнего уровня:
findFoo(...)
иfindBar(...)
. Это интерфейс к уровню ввода / вывода.Ваше описание источников данных следует , что существует два способа на А:
findFoo
иfindBar
и один метод на B:findFooAuxiliaryInformation
. ВfindFoo
вас нужно будет объединить информацию от А и Б.Я не уверен, о какой "жесткой связи" ты говоришь. Есть три типа данных , содержащихся в этих двух наборов данных:
Bar
,Foo
, иFooAuxData
. Связь междуFoo
иFooAuxData
присуща входным данным и не может быть уменьшена. Но эта связь должна появляться только вfindFoo
методе. Это лучшее, что вы можете сделать. Требование реализовано в одном месте. Если он меняется, вы должны изменить этот код.источник
Ты не можешь
Если я правильно понимаю,
Foo
иBar
откудаdsA
.Bar
s принадлежатFoo
s.Предпочтительно, чтобы вы не хотите ,
Bar
S , присвоенныйFoo
с, еслиFoo
не было дополнено ,Foo.enhancedInfo
что исходит отdsB
.Вы предпочитаете присваивать
Bar
sFoo
s, что создает тесную связь. Я бы назвал это «проблемой требований», которая заставляет вас идти по определенному пути.Таким образом, технические проблемы заключаются в том, что
dsB
может иметь или не иметь информацию о какой-либо информации,Foo
аdsB
может даже не быть доступной.Вам нужно решить, насколько сложным и быстрым является это предпочтение
Foo.enhancedInfo
. Основываясь на этом требовании, вы можете решить, предоставлять объектFoo
+Bar
или нет. Разрешение на предоставление расширенногоFoo
кода только усложняет логику и говорит мне, что предпочтение не так строго, как может показаться. Определите , какие вариантыFoo
,Foo.enhanced
иBar
ваше приложение (s) может поддерживать , и вы будете иметь свой окончательный ответ.Есть и другие вещи, которые вы можете сделать, чтобы
Foo
сблизить связанную информацию, и это может решить некоторые из этих проблем. То, как сформулирован ваш вопрос, звучит так, как будто вы имеете дело с проблемой на уровне объекта данных, и вы не сможете учесть изменения типа инфраструктуры.источник
Если данные в источнике данных B не могут стоять самостоятельно, вы, возможно, захотите перенести их в источник данных A, если это возможно.
Если они независимы, но связаны между собой, вам следует заняться виртуализацией данных . Это позволит приложениям обрабатывать данные как один набор (когда это необходимо) независимым образом. В зависимости от вашей платформы, вероятно, будет существующая инфраструктура / библиотека, которая поможет вам реализовать это.
источник