如何使用DDD/CQRS编写功能

LCJ*_*LCJ 6 .net c# design-patterns domain-driven-design cqrs

我有一个银行帐户域名,如下所示.可以有SavingsAccount,LoanAccount,FixedAccount等.一个用户可以拥有多个帐户.我需要添加一个新功能 - 为用户获取所有帐户.应该写的功能在哪里以及如何?

如果解决方案遵循SOLID原则(开放 - 封闭原则,......)和DDD,那将是很好的.

任何可以使代码更好的重构都是受欢迎的.

注意:AccountManipulator将由网站客户端通过Web服务使用.

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()
    {

    }
}
}
Run Code Online (Sandbox Code Playgroud)

读:

  1. 何时使用CQRS设计模式?

  2. 在域驱动设计中,在域对象中调用其他对象的repostiories会违反DDD吗?

  3. 重构访问遗留系统中存储库的域逻辑

  4. 以下哪些例子代表正确使用DDD?

  5. 良好的领域驱动设计样本

  6. 为每个对象创建通用存储库与特定存储库的优势?

Dav*_*ers 3

首先,要真正回答您的问题,重要的是要知道为什么需要获取所有用户帐户?你是:

  1. 获取要在屏幕上显示的帐户列表,以便用户然后针对单个帐户执行命令/事务?
  2. 对所有用户帐户执行单个命令/事务 - 例如“冻结所有用户帐户”?

我之所以这么问,是因为如果是后者,你只需要考虑DDD方面。如果这个“功能”的原因是前者(读完你的问题后我怀疑是这样) - 我真的建议创建一个薄查询服务层来获取屏幕所需的用户帐户数据。你不需要为此添加 DDD 的“限制”;不涉及任何事务或模型状态更改。提供此功能根本不必涉及域模型。只需定义一些简单的 POCO DTO 并使用实体框架来获取数据并将其传递回 UI。

这就是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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其中AccountService是一个web服务,即应用层。

总而言之,我的建议是:仅在需要事务的命令上下文中考虑 DDD 。用于获取数据列表;创建UI 可以使用的简单查询服务。

PS我注意到您的问题和一些答案中滥用了工厂模式。工厂旨在根据特定数据提供对象的创建策略。不应该有调用数据库的“GetAccount(accountId)”方法;存储库调用数据库,然后将数据传递到工厂以创建对象。

  • 蓝皮书 -&gt; http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215 (2认同)

归档时间:

查看次数:

2333 次

最近记录:

13 年,4 月 前