Как писать функции с помощью ДДД / с CQRS

У меня есть домен банковского счета, как указано ниже. Могут быть SavingsAccount, LoanAccount, FixedAccount и так далее. Один пользователь может иметь несколько учетных записей. Мне нужно добавить новую функциональность-получить все учетные записи для пользователя. Где должна быть написана функция и как?

было бы здорово, если решение следует твердым принципам( принцип открытого-закрытого,...) и DDD.

любой рефакторинг, который сделает код лучше, приветствуется.

Примечание: AccountManipulator будет использоваться клиентом веб-сайта через веб-службу.

namespace BankAccountBL
{
public class AccountManipulator
{
    //Whether it should beprivate or public?
    private IAccount acc;

    public AccountManipulator(int accountNumber)
    {
        acc = AccountFactory.GetAccount(accountNumber);
    }

    public void FreezeAccount()
    {
        acc.Freeze();
    }

}

public interface IAccount
{
    void Freeze();
}

public class AccountFactory
{
    public static IAccount GetAccount(int accountNumber)
    {
        return new SavingsAccount(accountNumber);
    }
}

public class SavingsAccount : IAccount
{
    public SavingsAccount(int accountNumber)
    {

    }

    public void Freeze()
    {

    }
}
}

читать:

  1. когда использовать шаблон проектирования CQRS?

  2. в доменном дизайне было бы нарушением DDD помещать вызовы репозиториев других объектов в объект домена?

  3. рефакторинг логики домена, которая обращается к репозиториям в устаревшем система

  4. какой из этих примеров представляет правильное использование DDD?

  5. хороший домен управляемые образцы дизайна

  6. преимущество создания общего репозитория против конкретного репозитория для каждого объекта?

1 ответов


во-первых, чтобы действительно ответить на ваш вопрос важно знать почему вы должны получить все учетные записи пользователей? Ты:

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

причина, по которой я спрашиваю, потому что вам нужно только рассмотреть аспект DDD, если это последнее. Если причина этой "функциональности" первая (и после прочтения вашего вопроса я подозреваю, что это так) - I действительно рекомендуется просто создать тонкий слой службы запросов, который получает данные учетной записи пользователя, необходимые для экрана. Для этого вам не нужно добавлять "ограничения" DDD; нет никаких транзакций или изменений состояния модели. Предоставление этой функции не должно включать модель предметной области на всех. Просто определите некоторые простые POCO DTO и используют Entity Framework для получения данных и передачи их обратно в пользовательский интерфейс.

Это CQRS примерно; вам не нужны репозитории, фабрики или агрегаты, чтобы дать UI список учетных записей для пользователя на выбор - вы бы усложнили его и сделали МНОГО больше работы для себя.

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

public class AccountService : IAccountService
{
    private IAccountRepository _accountRespository;

    public void FreezeAllAccountsForUser(Guid userId)
    {
        IEnumerable<IAccount> accounts = _accountRespository.GetAccountsByUserId(userId);

        using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
        {
            foreach (IAccount account in _accounts)
            {
                account.Freeze();
                _accountRespository.Save(account);
            }
        }
    }
}

где AccountService-это веб-сервис, т. е. уровень приложения.

вкратце, мой совет: рассмотрите только DDD в контексте команды требуют сделки. Для получения списков данных; создайте простой служба запросов, которую может использовать пользовательский интерфейс.

P. S. Я уже заметил