2012-02-08 4 views
5

Я пытаюсь создать небольшое демонстрационное веб-приложение, которое слабо связано, имеет высокую степень проверки, имеет хороший чистый код и т. Д. Короче говоря, я экспериментирую с тем, чтобы делать все правильно. ;)Совет по простой архитектуре приложений

Я в настоящее время есть три проекта в моем Wolfie растворе:

  • Wolfie.Core - содержит Хозяйствующие субъекты
  • Wolfie.Data - содержит код доступа к данным, ссылки Core.
  • Wolfie.Web - будет сайтом nancy.

В его нынешнем виде Core ничего не знает о каких-либо других проектах. Данные должны ссылаться на Core Core как на типы, возвращаемые Data. Поэтому в этот момент я понял, что Web должен будет ссылаться как на Core, так и на Data, чтобы иметь возможность работать, поскольку тип сущности находится в Core, а вызовы базы данных - в Data.

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

Я не думаю, что хочу поместить какой-либо код или ссылки на базу данных в Core, и я хочу, чтобы мои бизнес-правила были исключены из Data.

Это правильно ссылки на оба проекта из Интернета? или потребуется другой проект между Web и другими, чтобы Web ссылался только на одно место и не несет ответственности за вызов методов данных и т. д.

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

Надеюсь, что я сделал как-то, и я с нетерпением жду некоторых полезных ответов.

+0

Похоже, что у вас уже есть ответы. Вы абсолютно правы, чтобы изолировать логику бизнес-ядра от технологических реализаций. Это почти похоже на то, что вы знакомы с архитектурой Onion, описанной в блоге Джеффри Палермо и используемой в серии книг ASP.Net MVC In Action от него и других. – StarTrekRedneck

ответ

3

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

+2

Нет, это не так. Уровень пользовательского интерфейса не должен знать о реализации уровня данных. Однако пользовательский интерфейс может знать об абстракции уровня данных (в виде интерфейсов репозитория). – jgauffin

4

Я не думаю, что есть что-то по своей сути неправильно с этими двумя ссылками.

Но, я бы подумал, что такое «Ядро». Это ваша логика вашего домена? Если это так, я не уверен, что у меня будет ситуация, когда ваша сборка доступа к данным знает о вашей логике домена, и ваш уровень GUI знает обо всех.

Если «Core» является логикой домена, вы можете поместить в нее классы (например, IRepository Pattern), которые знают о сборке «Данные». Тогда ваша веб-сборка будет знать о «Core», но не «Data».

Чтобы облегчить эту компоновку, вы можете создать четвертую сборку под названием «DataTransfer» и определить некоторые объекты (или, еще лучше, интерфейсы), которые «Core», «Data» и «Web» знают и используют для связи друг с другом. На самом деле, если вы действительно хотите разобраться, структурирование вещей с помощью сборки «Типы», содержащей интерфейсы, может фактически сделать ее так, чтобы ни одна из ваших первоначальных трех сборок не знала друг о друге.

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

Edit: Для того, чтобы помочь визуализировать то, что я имею в виду, я говорю о слоистой ситуации:

Web 
| 
v 
Core 
| 
v 
DataAccess 

вместо:

Web 
| \ 
v \ 
Core | 
^ | 
| v 
DataAccess 

У вас есть три ссылки, когда вы могли бы заставить его работать с два. Дополнительное/ненужное соединение рано приводит к головной боли позже.

+0

Спасибо за совет. Поэтому, если Core теперь ссылается на Data, а не наоборот, какие типы будут возвращать/получать данные, поскольку они не будут знать о типах в Core? Мне нужны какие-то промежуточные типы (я думаю, это то, что вы подразумеваете под сборкой DataTransfer). – DavidGouge

+0

Да, точно. У сборника «DataTransfer» были бы POCOs или, еще лучше, интерфейсы, которые Core/Data/Web знал бы и мог бы использовать для связи через параметры и возвращаемые значения. –

+2

Ошибка корневой бизнес-логики (Core/Domain/etc.) Для ссылки на любую технологическую реализацию, такую ​​как база данных, файловая система и т. Д. Концепции бизнеса должны быть автономными. Уровень доступа к данным - это * реализация * бизнес-концепции, например, IOrderRepository или даже IRetrieveOrderProcess. Вот почему Core не должен ссылаться на DataAccess. – StarTrekRedneck

1

Архитектура 1. данные 2. бизнес-логика 3. клиент. Данные - это данные. Бизнес-логика работает с данными. Клиент подключается к бизнес-логике, такой как data-> business logic-> client. Клиент не подключается напрямую к данным. 3 слоя. клиент логики данных.

1

Я думаю, что это имеет смысл. До тех пор, пока вы отделяете Web от бизнес-уровня, он позволяет вам легче протестировать бизнес-логику, а также выставлять бизнес-уровень другими способами (например, веб-сервисами).

9

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

В этом приложении бизнес-логика домена была изолирована в своей собственной сборке «Домен» (ваша сборка «Core») и ничего не говорила за пределами платформы .NET. Для подключения к внешним бизнес-компонентам, таким как база данных и другие веб-службы, была сборка «Инфраструктура» (сборка «Данные»). Ключ для этого приложения заключается в том, что каждая реализация в сборке инфраструктуры была сопряжена в сборке Domain и возвратила объекты сборки домена (как вы описали). Это, конечно же, потребовало ссылки от Infrastructure to Domain.

Чтобы связать все это вместе, сборка «WebApp» (ваша сборка «Веб») ссылалась как на сборку «Домены», так и на «Инфраструктура» и использовала контейнер IoC для разрешения всех зависимостей приложений. Когда запросы поступают в WebApp, он разрешит соответствующий контракт «Домен» для обслуживания запроса, который начнет цепочку вызовов разрешения IoC. Вне регистрации реализации инфраструктуры сборка WebApp не заботится о том, чтобы сборка Infrastructure существовала.

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

  • Там нет никаких внешних ссылок в области бизнеса.
  • Приложение бизнес-домена полностью независимо от интерфейса веб-интерфейса и базы данных.

Это придает много проверяемости к вашей области бизнеса и много гибкости в том, как фронт-эндов интерфейс с доменом. Фактически, эта гибкость составляет, что делает ее настолько проверяемой. Эта гибкость имеет и другие преимущества. Например, с изолированным бизнес-доменом вы можете легко создать новый интерфейс CLI или WPF, подключенный к файловой системе без изменения кода бизнес-домена, если вы хотите развернуть и запустить свой клиент локально на машине.

Хотя этот пример может показаться немного надуманным, в случае приложения, на которое я ссылался выше, команда разработчиков рассматривает возможность создания интерфейса веб-служб в дополнение к уже существующему интерфейсу веб-сайта MVC. Это только реальная возможность для этой команды, потому что они настраивают это приложение, как вы описываете.

+0

ДА! Вот как это делается, друзья. – StarTrekRedneck

+0

Хорошая история! (а ремонтопригодность еще больше возрастает, если у вас есть сервисный уровень, реализация пользовательского интерфейса и веб-сервисов становится довольно простой). – mikalai

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