Restringi il modello di dominio se il servizio non viene utilizzato

2

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

    
posta keelerjr12 06.11.2018 - 18:26
fonte

1 risposta

3

Nessun client dovrebbe essere costretto a dipendere da metodi che non usa.

Il nome di fantasia per questa idea è il principio di segregazione dell'interfaccia . Tuttavia, questo può sembrare molto fastidioso per qualcuno che vuole solo creare un servizio.

Aiuta a smettere di concentrarsi sul servizio. Fai finta che non esista per un momento. Guarda il tuo cliente e chiedi di cosa ha bisogno. Costruisci qualcosa che prometta al cliente ciò di cui ha bisogno. Qualunque cosa sia, lascia che sia il cliente a definirla. Nient'altro ha il diritto di causare cambiamenti nell'interfaccia delle cose, ma il client.

Quando la pensi in questo modo, i clienti hanno le interfacce che usano (parola chiave o altro). Quando un servizio implementa quell'interfaccia, quel servizio non pubblica la sua interfaccia. È promettente che possa fare ciò di cui hanno bisogno i client che usano quell'interfaccia.

Se ci pensi in questo modo, non è davvero strano lasciare semplicemente AddTransaction() dall'interfaccia che il client vede, indipendentemente dal fatto che altri possano vederlo su altre interfacce implementate. Quando il cliente non sa che esiste non farà del male a nulla.

    
risposta data 07.11.2018 - 04:02
fonte

Leggi altre domande sui tag