SOA на основе контракта: разработка бизнес-домена: WCF - PullRequest
2 голосов
/ 29 февраля 2012

Я строю совершенно новую систему, используя WCF.Я собираюсь использовать подход сначала контракта для сервиса, который должен быть построен на основе сервис-ориентированных концепций.У меня есть сервисная операция, которая возвращает банковские реквизиты пользователя.Учетная запись может быть типа «FixedAccount» или «SavingsAccount».Я разработал сервис следующим образом.

[ServiceContract]
interface IMyService
{
[OperationContract]
AccountSummary AccountsForUser(User user);
}


[DataContract]
class AccountSummary
{
 [DataMember]
 public string AccountNumber {get;set;}

 [DataMember]
 public string AccountType {get;set;}
}

Это хорошо.

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

1) Подход 1 : придумать базовый класс BankAccount.Производные от него специализированные классы - «FixedAccount» и «SavingsAccount».У BankAccount будет метод Transfer (строка toAccount).Это становится нашим знакомым и эффективным OOAD.Это включает маппер для сопоставления между классами доменов AccountSummary DTO и FixedAccount / SavingsAccount.

2) Подход 2 : без использования слоя перевода mapper.

Вопросы

1) Предположим, я использую подход 1. Существует ли какая-нибудь статья / учебное пособие, в котором объясняется, как сопоставить AccountSummary DTO с классами домена FixedAccount / SavingsAccount на основе значения AccountType в DTO (условное сопоставление)?

2) Как мне выполнить задачу в подходе 2?


ЧТЕНИЕ: -

  1. http://www.soapatterns.org/service_facade.php

  2. Доступ к данным архитектуры SOA

  3. Проектирование сервисов и операций в WCF

  4. Данные контракта WCF и данные эталонного объекта?

  5. Когда логика принадлежит бизнес-объекту / объекту и когда она принадлежит сервису?

Ответы [ 3 ]

3 голосов
/ 01 марта 2012

Прежде всего - вам нужно понять, действительно ли вам нужна полноценная SOA.

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

Будет ли ваше приложение "общаться" с любым другим приложением?

Если нет, и вы просто создаете монолитный веб-сайт, освободите свой разум и избавьтесь от этого SOA-буллпрапа. В противном случае вы получите бесполезный слой абстракции.

Это единственный способ применить второй подход, потому что вы не можете полностью отделить модель предметной области, не сопоставив ее с чем-то другим.


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

Есть ли статья / учебное пособие, в которых объясняется, как сопоставить AccountSummary DTO с FixedAccount / SavingsAccount

Картирование само по себе не сложная идея. Вот один простой способ сопоставления объектов:

class AccountSummary{
  public string InterestingThing {get; set;}
  public string AnotherThing {get; set;}
}
class AccountSummaryMapper{
   public static Map(BankAccount a){
    return new AccountSummary{
        InterestingThing=a.SomethingSomething,
        AnotherThing=a.Something.Else.ToString()
      };
   }
}
var accountSummary=
  AccountSummaryMapper.Map(myBankAccount);

Это может показаться неэффективным. Могут помочь сопоставления объект-объект, такие как Automapper . Пройдите учебник, он должен быть достаточно хорош, чтобы вы начали. Идея несложная - вы создаете Карты, сообщаете о них Mapper при запуске приложения, а затем используете Mapper для сопоставления ваших объектов с заданной конфигурацией.


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

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

Отображение AccountSummary непосредственно в BankAccount и восстановление его состояния похоже на выполнение домашней работы. Там не должно быть необходимости в таком отображении. Вместо этого - сообщите BankAccount BankAccount.DoHomework (карандаш, тетрадь, некоторые сильные слова).


развивать бизнес-домен

Вы не разрабатываете бизнес-домен. Вы разрабатываете модель предметной области, которая является просто отражением бизнес-предметной области, созданной для решения конкретных проблем.

2 голосов
/ 03 марта 2012

Прежде чем вы поймете эту часть, вам нужно решить, что ваши клиенты будут получать от каждого вызова метода обслуживания.Нужен ли клиенту FixedAccount / SavingsAccount, или ему действительно нужен AccountSummary?

Если метод (как в вашем примере) просто возвращает AccountSummary, то один простой способ сделать это - добавитьметод к BankAccount, который создает AccountSummary.Затем, когда вы хотите что-то вернуть (независимо от типа учетной записи, но при условии, что ваши две учетные записи наследуются от BankAccount), вы просто делаете это:

return someAccount.ToSummary()

Некоторые люди скажут вам, что это не так "«чисто», в том смысле, что вы теперь знаете класс BankAccount о вашем AccountSummary, но лично мне всегда было легче работать с ним.Если вам это не нравится, такие инструменты, как AutoMapper, также могут делать это довольно эффективно (как уже упоминалось в других ответах).

Если вы возвращаете какой-то производный класс, а не сам фактический класснет способа обойти это где-то (если вы используете AutoMapper или что-то пишете сами).Единственный способ избежать необходимости выполнять какое-либо сопоставление - это вернуть сам BankAccount, что не рекомендуется для службы, поскольку внутренние изменения в классе могут повлиять на службу.Это легко запомнить сейчас, но также легко забыть об этом через 3 года, когда другой разработчик занимается обслуживанием.Сопоставление также отправляет только те вещи, которые вы явно указали в сервисе, поэтому опять же помогает избежать ошибок, которые пропускают данные.

Содержимое BankAccount.ToSummary () довольно простое

public AccountSummary ToSummary()
{
    AccountSummary s = new AccountSummary();
    s.AccountNumber = AccountNumber();
    s.Balance = Balance()
    return s;
}
2 голосов
/ 29 февраля 2012

Для первого подхода рассмотрите возможность использования такого инструмента, как AutoMapper, а не реализации сопоставления вручную.Может спасти вас много боли. AutoMapper

...