Logicamente come posso evitare che un client apporti modifiche a un'entità modello di dominio se non si utilizza un servizio? Ad esempio:
Diciamo che ho una classe Account che contiene Transazioni per calcolare un saldo. Un servizio viene utilizzato per coordinare l'interazione di queste entità. Tuttavia, desidero che un client sia in grado di utilizzare funzioni specifiche (ad esempio CurrentBalance, BalanceByDate () e così via). Non voglio consentire loro l'accesso a AddTransaction senza utilizzare il servizio. Un DTO sembra strano dato che non si tratta veramente di limiti di transizione.
Account
public class Account
{
public decimal CurrentBalance()
{
// return current balance
}
public decimal BalanceByDate(DateTime date)
{
// return balance through date
}
// Want to restrict usage of this to a service only
// to coordinate interaction of multiple entities to
// prevent corruption to the accounting system
public void AddTransaction(Transaction trans)
{
// add transaction to list of transactions
}
}
AccountingService
public class AccountingService
{
public void AddTransaction(Transaction trans)
{
foreach (var account in trans.Accounts)
account.AddTransaction(trans); // method in question
}
public Account GetAccount(int ID)
{
// return account by id
}
}
Client
var accountingService = new AccountingService();
// build transaction here
var transaction = TransactionFactory.Create(/*blah*/);
accountingService.AddTransaction(transaction);
// but this would be harmful to the system...
var account = accountingService.GetAccount(accountID);
account.AddTransaction(new Transaction(/*junk data*/));
// however, still want to get the balance of the account
var balance = account.CurrentBalance();
Quindi come fa la maggior parte delle persone a gestirlo? Esporre interfacce diverse in modo che i clienti usino qualcosa di diverso? L'account implementa IAccountable IT IT trasferibile? O semplicemente restituire qualche tipo di account di sola lettura dove chiamare AddTransaction () interessa davvero solo quell'oggetto? Un'altra idea era quella di iniettare un elenco di transazioni nel costruttore Account e rimuovere il metodo AddTransaction ().