Архитектура API - PullRequest
       23

Архитектура API

5 голосов
/ 20 декабря 2010

Я нахожусь в процессе разработки API. Я хотел бы знать, является ли то, что я придумал, хорошим решением:

У меня есть слой данных типа репозитория, который взаимодействует с базой данных путем преобразования бизнес-классов в сущности (сгенерированные из LLBL GEN, я не хотел использовать сущности напрямую как свои бизнес-объекты, потому что хотел, чтобы они были простыми и позвольте мне переключиться на Entity Framework или какой-либо другой маппер, если это необходимо)

У меня есть слой службы WCF, который я использую как тип фасада. Он вызывает уровень репозитория, преобразует бизнес-объекты в DTO и передает их через вызов службы API через сообщение клиенту. Клиент может быть веб-сайтом ASPX, приложением Silverlight, приложением WPF или даже приложением WP7. Проблема, с которой я продолжаю работать, заключается в том, что когда я хочу запустить бизнес-логику, я должен отправить DTO обратно в службу WCF, а затем обратно к клиенту. Это не кажется мне правильным. Я не могу поместить бизнес-логику в DTO, потому что это противоречит цели. Но если я хочу, чтобы код бизнес-типа выполнялся на клиенте, у меня много дублирования кода на разных клиентах.

Мой бизнес-уровень не знает об уровне данных, мой уровень данных знает о бизнес-уровне, а мой фасадный уровень знает о уровне данных, бизнес-уровне и DTO. Это плохой дизайн для API? И может ли кто-нибудь предложить мне какие-либо предложения? Я узнал о приложениях уровня предприятия только через чтение различных статей в Интернете.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 20 декабря 2010

Отношения между слоями

Если я хорошо понимаю ваш дизайн, бизнес-уровень не знает (= не использует) уровень данных, и фасад фактически связывает их, переводя DAO в DTO и наоборот.

Вам следует рассмотреть несколько иной подход: определить интерфейсы для всех объектов, связанных с данными (независимо от того, являются ли они DAO или DTO), и использовать контейнер Inversion-of-Control для объединения бизнес-уровня и уровня доступа к данным. Причина в том, что в вашем проекте вы можете быстро столкнуться с невозможностью получить дополнительные данные прямо на бизнес-уровне. Вы бы в конечном итоге заменили этот фасад фасадом и, следовательно, использовали слишком много реальной бизнес-логики.

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

Использование DTO

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

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

Представьте себе простой API Get / Update, такой как этот:

CustomerDTO GetCustomer(int customerID);

CustomerDTO UpdateCustomerAddress(int customerID, AddressDTO address);

CustomerDTO UpdateCustomerPrimaryContact(int customerID, PersonDTO primaryContact);

Вы используете идентификатор для идентификации клиента и передаете в DTO, который представляет собой подмножество обновляемой записи клиента (независимо от базовой архитектуры данных). out DTO представляет клиента в целом, упрощая задачу уровня представления обновлений информации, отображаемой для пользователя. Преимущество заключается в том, что бэкэнду не нужно знать, какое подмножество данных клиента действительно необходимо для уровня представления, а уровень представления может передавать бэкэнду только те части, которые действительно были изменены.

Обновление - техническое примечание: Рассмотрите возможность использования такого инструмента, как AutoMapper (C #), для автоматизации переводов между DTO и DAO. Хотя этот вопрос является предметом используемой технологии, в целом такой подход экономит много ручной работы и способен устранить трудно обнаруживаемые ошибки. Наличие такой системы автоматизации перевода объектов помогает продвигать лучшие методы проектирования и позволяет создавать более специализированные и, следовательно, семантически более точные DTO.


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

3 голосов
/ 20 декабря 2010

Мой бизнес-уровень не знает об уровне данных, мой уровень данных знает о бизнес-уровне, а мой фасадный уровень знает о уровне данных, бизнес-уровне и DTO.Это плохой дизайн для API?

Ни один слой не должен знать о слое выше.

У меня есть слой службы WCF, который я использую как тип фасада.Он вызывает уровень репозитория, преобразует бизнес-объекты в DTO и передает их через вызов службы API через сообщение клиенту.Клиент может быть веб-сайтом ASPX, приложением Silverlight, приложением WPF или даже приложением WP7

Существует принцип дизайна, называемый Вам это не нужно, это почти то же самое, что и Keep It Simple (и) глупо .

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

Если вам понадобится служба WCF позже, добавьте ее позже.

Если вы определяете сервисы, используя интерфейсы, вполне достаточно поменять реализацию, которую вы используете, непосредственно на реализацию сервиса WCF.(если вы используете контейнер IoC )

Бетонирование против интерфейсов

Интерфейсы и бизнес-объекты всегда следует помещать в отдельную сборку изреализации (классы), чтобы облегчить замену реализаций каждого уровня.Это шаблон проектирования, называемый Разделенное взаимодействие , о котором вы можете прочитать здесь: http://martinfowler.com/eaaCatalog/separatedInterface.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...