gpt4 book ai didi

c# - 访问外部信息的 DDD 方法

转载 作者:太空宇宙 更新时间:2023-11-03 20:24:47 24 4
gpt4 key购买 nike

我有一个现有的银行应用程序类,如下所示。银行账户可以是 SavingsBankAccount 或 FixedBankAccount。有一个名为 IssueLumpSumInterest 的操作。对于 FixedBankAccount,仅当账户所有者没有其他账户时才需要更新余额。

这要求 FixedBankAccount 对象了解帐户所有者的其他帐户。如何按照 SOLID/DDD/GRASP/Information Expert 模式做到这一点?

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);
}
}

}

阅读

  1. Issue in using Composition for “is – a “ relationship

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

  3. 构建 LINQ to SQL 应用程序

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

  5. Confusion between DTOs (linq2sql) and Class objects!

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

最佳答案

我首先注意到的是银行帐户工厂的不当使用。与您拥有的工厂几乎一样,存储库应该使用该工厂来根据从数据存储中检索到的数据创建实例。因此,您对 accountRepository.FindByID 的调用将返回 FixedBankAccount 或 SavingsBankAccount 对象,具体取决于从数据存储返回的 AccountType。

如果利息仅适用于 FixedBankAccount 实例,那么您可以执行类型检查以确保您使用的是正确的帐户类型。

public void IssueLumpSumInterest(int accountId)
{
var account = _accountRepository.FindById(accountId) as FixedBankAccount;

if (account == null)
{
throw new InvalidOperationException("Cannot add interest to Savings account.");
}

var ownerId = account.OwnerId;

if (_accountRepository.Any(a => (a.BankUser.UserId == ownerId) && (a.AccountId != accountId)))
{
throw new InvalidOperationException("Cannot add interest when user own multiple accounts.");
}

account.AddInterest();

// Persist the changes
}

注意:FindById 应该只接受 ID 参数而不是 lambda/Func。您已通过名称“FindById”指示搜索的执行方式。将“accountId”值与 BankAccountId 属性进行比较这一事实是隐藏在该方法中的实现细节。如果您想要使用 lambda 的通用方法,请将方法命名为“FindBy”。

如果所有实现都不支持该行为,我也不会将 AddInterest 放在 IBankAccount 接口(interface)上。考虑公开 AddInterest 方法的单独 IInterestEarningBankAccount 接口(interface)。我还会考虑在上面的代码中使用该接口(interface)而不是 FixedBankAccount,以便在您将来添加支持此行为的其他帐户类型时使代码更易于维护和扩展。

关于c# - 访问外部信息的 DDD 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11241541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com