DDD的方式获取外部信息方式、信息、DDD

由网友(坐在坟头调戏鬼)分享简介:我有一个现有的银行应用程序类,如下图所示。该银行帐户可以是SavingsBankAccount或FixedBankAccount的。有称为IssueLumpSumInterest的操作。为FixedBankAccount,天平需要更新只有当帐户的拥有者没有其他帐户。 这需要在FixedBankAccount对象了解账户...

我有一个现有的银行应用程序类,如下图所示。该银行帐户可以是SavingsBankAccount或FixedBankAccount的。有称为IssueLumpSumInterest的操作。为FixedBankAccount,天平需要更新只有当帐户的拥有者没有其他帐户。

这需要在FixedBankAccount对象了解账户所有人的其他账户。如何通过以下要做到这一点的固体 / DDD / GRASP /信息专家模式?

 命名空间ApplicationServiceForBank
{

公共类BankAccountService
{
    RepositoryLayer.IRepository< RepositoryLayer.BankAccount> accountRepository;
    ApplicationServiceForBank.IBankAccountFactory bankFactory;

    公共BankAccountService(RepositoryLayer.IRepository< RepositoryLayer.BankAccount>回购,IBankAccountFactory bankFact)
    {
        accountRepository =回购;
        bankFactory = bankFact;
    }

    公共无效IssueLumpSumInterest(INT acccountID)
    {
        RepositoryLayer.BankAccount oneOfRepositroyAccounts = accountRepository.FindByID(P => p.BankAccountID == acccountID);

        INT OWNERID =(INT)oneOfRepositroyAccounts.AccountOwnerID;
        IEnumerable的< RepositoryLayer.BankAccount> accountsForUser = accountRepository.FindAll(P => p.BankUser.UserID == OWNERID);

        DomainObjectsForBank.IBankAccount domainBankAccountObj = bankFactory.CreateAccount(oneOfRepositroyAccounts);

        如果(domainBankAccountObj!= NULL)
        {
            domainBankAccountObj.BankAccountID = oneOfRepositroyAccounts.BankAccountID;
            domainBankAccountObj.AddInterest();

            this.accountRepository.UpdateChangesByAttach(oneOfRepositroyAccounts);
            //oneOfRepositroyAccounts.Balance = domainBankAccountObj.Balance;
            this.accountRepository.SubmitChanges();
        }
    }
}

公共接口IBankAccountFactory
{
    DomainObjectsForBank.IBankAccount CreateAccount(RepositoryLayer.BankAccount repositroyAccount);
}

公共类MySimpleBankAccountFactory:IBankAccountFactory
{
    公共DomainObjectsForBank.IBankAccount CreateAccount(RepositoryLayer.BankAccount repositroyAccount)
    {
        DomainObjectsForBank.IBankAccount ACC = NULL;

        如果(String.Equals(repositroyAccount.AccountType,固定))
        {
            ACC =新DomainObjectsForBank.FixedBankAccount();
        }

        如果(String.Equals(repositroyAccount.AccountType,储蓄))
        {
            // ACC =新DomainObjectsForBank.SavingsBankAccount();
        }

        返回ACC;
    }
}

}

命名空间DomainObjectsForBank
{

公共接口IBankAccount
{
    INT BankAccountID {获得;组; }
    双平衡{获得;组; }
    字符串AccountStatus {获得;组; }
    无效FreezeAccount();
    无效AddInterest();
}

公共类FixedBankAccount:IBankAccount
{
    公众诠释BankAccountID {获得;组; }
    公共字符串AccountStatus {获得;组; }
    公共双平衡{获得;组; }

    公共无效FreezeAccount()
    {
        AccountStatus =冻结;
    }

    公共无效AddInterest()
    {
        //要做到:平衡需要更新仅如果这个人有没有其他帐户。
        余额=余额+(平衡* 0.1);
    }
}

}
 

阅读

Issue使用成分为是 - 个关系

实现业务逻辑(LINQ到SQL) http://msdn.microsoft.com/en-us/library/bb882671.aspx

架构设计的LINQ to SQL应用程序

探索N层架构使用LINQ到SQL http://randolphcabral.word$p$pss.com/2008/05/08/exploring-n-tier-architecture-with-linq-to-sql-part-3-of-n/

Confusion的DTO(LINQ2SQL)和类对象之间!

Domain驱动设计(LINQ到SQL) - 如何删除聚集的部位

解决方案

从阅读您的要求,这里是我会怎么做:

  //应用服务 - 通过UI消耗
公共类的Account:IAccountService
{
    私人只读IAccountRepository _accountRepository;
    私人只读ICustomerRepository _customerRepository;

    公共ApplicationService(IAccountRepository accountRepository,ICustomerRepository customerRepository)
    {
        _accountRepository = accountRepository;
        _customerRepository = customerRepository;
    }

    公共无效IssueLumpSumInterestToAccount(GUID帐户ID)
    {
        使用(IUnitOfWork的UnitOfWork = UnitOfWorkFactory.Create())
        {
            帐户帐户= _accountRepository.GetById(帐户ID);
            客户客户= _customerRepository.GetById(account.CustomerId);

            account.IssueLumpSumOfInterest(客户);

            _accountRepository.Save(账户);
        }
    }
}

公共类客户
{
    私人列表<的Guid> _accountIds;

    公开的IEnumerable<的Guid> AccountIds
    {
        {返回_accountIds.AsReadOnly();}
    }
}

公共抽象类账户
{
    公共抽象无效IssueLumpSumOfInterest(客户的客户);
}

公共类FixedAccount:帐户
{
    公众覆盖无效IssueLumpSumOfInterest(客户的客户)
    {
        如果(customer.AccountIds.Any(ID =>!ID = this._accountId))
            抛出新的异常(包干不能发给定期账户,其中客户有其他帐户);

        // code到这里问题的关注
    }
}

公共类SavingsAccount:帐户
{
    公众覆盖无效IssueLumpSumOfInterest(客户的客户)
    {
        // code到这里问题的关注
    }
}
 
DDD微服务架构设计第一课 DDD落地与实现演练

在 IssueLumpSumOfInterest 的帐户总方法需要客户聚集,以帮助决定是否应该发出的兴趣。 在客户总包含账户ID列表 - 不会一个账户聚集的名单。 在基类的帐户有一个多态的方法 - 在FixedAccount检查,客户没有任何其他账户 - 的SavingsAccount不会做这种检查。

I have an existing bank application classes as shown below. The banks account can be of SavingsBankAccount or FixedBankAccount. There is an operation called IssueLumpSumInterest. For FixedBankAccount, the balance need to be updated only if the owner of the account has no other account.

This demands the FixedBankAccount object to know about other accounts of the account owner. How to do this by following SOLID/DDD/GRASP/Information Expert pattern?

namespace ApplicationServiceForBank
{

public class BankAccountService
{
    RepositoryLayer.IRepository<RepositoryLayer.BankAccount> accountRepository;
    ApplicationServiceForBank.IBankAccountFactory bankFactory;

    public BankAccountService(RepositoryLayer.IRepository<RepositoryLayer.BankAccount> repo, IBankAccountFactory bankFact)
    {
        accountRepository = repo;
        bankFactory = bankFact;
    }

    public void IssueLumpSumInterest(int acccountID)
    {
        RepositoryLayer.BankAccount oneOfRepositroyAccounts = accountRepository.FindByID(p => p.BankAccountID == acccountID);

        int ownerID = (int) oneOfRepositroyAccounts.AccountOwnerID;
        IEnumerable<RepositoryLayer.BankAccount> accountsForUser = accountRepository.FindAll(p => p.BankUser.UserID == ownerID);

        DomainObjectsForBank.IBankAccount domainBankAccountObj = bankFactory.CreateAccount(oneOfRepositroyAccounts);

        if (domainBankAccountObj != null)
        {
            domainBankAccountObj.BankAccountID = oneOfRepositroyAccounts.BankAccountID;
            domainBankAccountObj.AddInterest();

            this.accountRepository.UpdateChangesByAttach(oneOfRepositroyAccounts);
            //oneOfRepositroyAccounts.Balance = domainBankAccountObj.Balance;
            this.accountRepository.SubmitChanges();
        }
    }
}

public interface IBankAccountFactory
{
    DomainObjectsForBank.IBankAccount CreateAccount(RepositoryLayer.BankAccount repositroyAccount);
}

public class MySimpleBankAccountFactory : IBankAccountFactory
{
    public DomainObjectsForBank.IBankAccount CreateAccount(RepositoryLayer.BankAccount repositroyAccount)
    {
        DomainObjectsForBank.IBankAccount acc = null;

        if (String.Equals(repositroyAccount.AccountType, "Fixed"))
        {
            acc = new DomainObjectsForBank.FixedBankAccount();
        }

        if (String.Equals(repositroyAccount.AccountType, "Savings"))
        {
            //acc = new DomainObjectsForBank.SavingsBankAccount();
        }

        return acc;
    }
}

}

namespace DomainObjectsForBank
{

public interface IBankAccount
{
    int BankAccountID { get; set; }
    double Balance { get; set; }
    string AccountStatus { get; set; }
    void FreezeAccount();
    void AddInterest();
}

public class FixedBankAccount : IBankAccount
{
    public int BankAccountID { get; set; }
    public string AccountStatus { get; set; }
    public double Balance { get; set; }

    public void FreezeAccount()
    {
        AccountStatus = "Frozen";
    }

    public void AddInterest()
    {
        //TO DO: Balance need to be updated only if the person has no other accounts.
        Balance = Balance + (Balance * 0.1);
    }
}

}

READING

Issue in using Composition for "is – a " relationship

Implementing Business Logic (LINQ to SQL) http://msdn.microsoft.com/en-us/library/bb882671.aspx

Architecting LINQ to SQL applications

Exploring N-Tier Architecture with LINQ to SQL http://randolphcabral.wordpress.com/2008/05/08/exploring-n-tier-architecture-with-linq-to-sql-part-3-of-n/

Confusion between DTOs (linq2sql) and Class objects!

Domain Driven Design (Linq to SQL) - How do you delete parts of an aggregate?

解决方案

From reading your requirement, here is how I would do it:

//Application Service - consumed by UI
public class AccountService : IAccountService
{
    private readonly IAccountRepository _accountRepository;
    private readonly ICustomerRepository _customerRepository;

    public ApplicationService(IAccountRepository accountRepository, ICustomerRepository customerRepository)
    {
        _accountRepository = accountRepository;
        _customerRepository = customerRepository;
    }

    public void IssueLumpSumInterestToAccount(Guid accountId)
    {
        using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
        {
            Account account = _accountRepository.GetById(accountId);
            Customer customer = _customerRepository.GetById(account.CustomerId);

            account.IssueLumpSumOfInterest(customer);

            _accountRepository.Save(account);
        }
    }
}

public class Customer
{
    private List<Guid> _accountIds;

    public IEnumerable<Guid> AccountIds
    {
        get { return _accountIds.AsReadOnly();}
    }
}

public abstract class Account
{
    public abstract void IssueLumpSumOfInterest(Customer customer);
}

public class FixedAccount : Account
{
    public override void  IssueLumpSumOfInterest(Customer customer)
    {
        if (customer.AccountIds.Any(id => id != this._accountId))
            throw new Exception("Lump Sum cannot be issued to fixed accounts where the customer has other accounts");

        //Code to issue interest here
    }
}   

public class SavingsAccount : Account
{
    public override void  IssueLumpSumOfInterest(Customer customer)
    {
        //Code to issue interest here
    }
}

The IssueLumpSumOfInterest method on the Account aggregate requires the Customer aggregate to help decide whether interest should be issued. The customer aggregate contains a list of account IDs - NOT a list of account aggregates. The base class 'Account' has a polymorphic method - the FixedAccount checks that the customer doesn't have any other accounts - the SavingsAccount doesn't do this check.

阅读全文

相关推荐

最新文章