2011-07-19 9 views
1

ドメイン駆動型設計に従うときにサービスクラスを実際に実装する最良の方法は何ですか?ドメイン駆動型設計でサービスをどのように実装する必要がありますか?

たとえば、1つのアカウントから別のアカウントに資金を振り替えるために使用できるAccountServiceが必要ですか?次のうち、これを実装する最良の方法はどれですか?

public class AccountService1 
{ 
    private IAccountRepository _accountRepo; 

    public AccountService1(IAccountRepository accountRepo) 
    { 
     _accountRepo = accountRepo; 
    } 

    public void TransferFunds(double ammount, int sourceAccountNumber, int targetAccountNumber) 
    { 
     //FUNDS TRANSFER CODE 
    } 
} 

public class AccountService2 
{ 
    public void TransferFunds(double ammount, Account sourceAccount, Account targetAccount) 
    { 
     //FUNDS TRANSFER CODE 
    } 
} 


public static class AccountService3 
{ 
    public static void TransferFunds(double amount, Account sourceAccount, Account targetAccount) 
    { 
     //FUNDS TRANSFER CODE 
    } 
} 

public static class AccountService4 
{ 
    public static void TransferFunds(double amount, int sourceAccountNumber, int targetAccountNumber, IAccountRepository repository) 
    { 
     //FUNDS TRANSFER CODE 
    } 
} 

答えて

0

最初の実装が最適です。ただし、金額と対象のAccountインスタンスも受け入れるAccountクラス自体にTransferメソッドを実装する必要があります。この場合のサービスの役割は、リポジトリを使用してAccountインスタンスをロードし、保存し、作業単位管理だけでなく、必要な外部サービスへのアクセスを提供することです。 Accountクラスの転送方式の役割Accountクラス自体内のデータの整合性を保護し、一貫性を確保するため、例外をスローすることがあるなど

class Account { 

    public string State { get; private set; } 

    public decimal Total { get; private set; } 

    public void Transfer(decimal amount, Account dest) { 
    if (amount > this.Total) throw Exception(); 

    if (this.State == "Closed") throw Exception(); 

    this.Total -= amount; 
    dest.Total += amount; 

    } 
} 

だからAccountクラスは、操作が可能とサービスであるかを定義します層はドメイン層上で動作するものであり、従ってすべての動作上の責任に関係する。

3

すべての方法で、貧血のドメインにつながります。

アカウントエンティティでインスタンスメソッドにすることができない理由はありますか?

public class Account { 
    public void Transfer(decimal amount, Account recipient); 
} 
2

例がアプリケーションサービスかドメインサービスかどうかは不明です。例1はアプリケーションサービスの外観、例2はドメインサービスの外観です。まとめると、次のようになります。

public class AccountApplicationService 
{ 
    private IAccountRepository _accountRepo; 

    public AccountApplicationService(IAccountRepository accountRepo) 
    { 
     _accountRepo = accountRepo; 
    } 

    public void TransferFunds(double ammount, int sourceAccountNumber, int targetAccountNumber) 
    { 
     Account sourceAccount = _accountRepo.GetById(sourceAccountNumber); 
     Account targetAccount = _accountRepo.GetById(targeteAccountNumber); 

     IAccountDomainService accDomService = new AccountDomainService(); 

     accDomService.TransferFunds(ammount, sourceAccount, targetAccount); 

     using(Transaction tran = _accountRepo.BeginTransaction()) //note: pseudo code. 
     { 
      _accountRepo.Save(sourceAccount); 
      _accountRepo.Save(targetAccount); 
      tran.Commit(); 
     } 
    } 
} 
関連する問題