DDD Relazioni tra entità figlio / oggetti valore

1

Sono nuovo di DDD e cerco di capirci qualcosa scrivendo un prototipo per un'applicazione (Core-Logic-Layer).

Il mio modello di dominio è simile a questo atm. (Ho estratto le parti, che non erano necessarie per il problema):

QuindiabbiamounaradiceaggregataDebitAccountchehaassegnatoEstimations(suicosti/entratechesiverificanoinundatointervallo).HaancheassegnatoPostingschesièverificatofisicamente(costo/reddito)inunadeterminatadata.

UnPostingpuòverificarsiconunastimaassegnata(ades."Abbiamo i costi mensili per pagare l'affitto"), ma potrebbe anche non esistere ("Il mio blocco note si è rotto, quindi ho bisogno di acquistarne uno nuovo").

Ecco il codice (imho) necessario per implementare il modello:

public class DebitAccount : BaseEntity
{
    protected ICollection<Estimation>     _Estimations;
    protected ICollection<Posting>        _Postings;

    public virtual IEnumerable<Estimation> Estimations
    {
        get 
        {
            return new List<Estimation>(_Estimations);
        }
    }

    public virtual IEnumerable<Posting> Postings
    { 
        get
        {
            return new List<Posting>(_Postings);
        }
    }
    public void Post(Posting posting)
    {
        var associatedEstimation = _Estimations.FirstOrDefault(e => e == posting.BelongsToEstimation);
        if(associatedEstimation == null)
        {
            var now  = _DateProvider.GetCurrentDate();
            var guid = Guid.NewGuid();
            associatedEstimation    = new Estimation(new Posting[] { posting }, new Amount(0, _CurrencyProvider.GetDefaultCurrency()), posting.PostingName, new DayInterval(now, now, 0),new EstimationId(guid));
            _Estimations.Add(associatedEstimation);
        }
        _Postings.Add(posting);
    }
    public DebitAccount TransferAmountTo(DebitAccount to, Amount amount, string transferName)
    {
        var currentDate = _DateProvider.GetCurrentDate();

        var fromPosting = new Posting(amount.Invert(),transferName, currentDate, null);
        var toPosting   = new Posting(amount.Clone() ,transferName, currentDate, null);

        this.Post(fromPosting);
        to.Post(toPosting);

        return this;
    }
}

Ci sono diversi problemi che sto affrontando:

  1. Quando si chiama Post -Method di un account di debito, come ottenere Estimation a cui appartiene la pubblicazione (se ce ne sono)? Nel codice dell'applicazione, è possibile ottenere tutte le stime dalla proprietà pubblica, trovare quella corretta e assegnarla alla registrazione corrente. Ma questo richiede al cliente di sapere che deve cercare la stima nella proprietà.

  2. Il prossimo problema è simile al primo: quando si trasferisce su un altro DebitAccount , come trovare il corrispondente Estimation (se esiste)?

  3. TransferTo -Function: dove e come persistere entrambi DebitAccounts . Deve assumere il codice chiamante (ad esempio il livello applicazione), che implicitamente il% passatoDebitAccount ( to ) è stato modificato (call-by-reference) e semplicemente persistono entrambi in un repository?

Come potrebbero essere affrontati questi problemi? O forse ho sbagliato e il mio design DDD è difettoso? Qualsiasi idea, commento e pensiero è apprezzata :)

    
posta Anton Rhein 05.09.2018 - 13:04
fonte

1 risposta

1

Penso che il riferimento diretto all'oggetto da Posting a Estimate sia un po 'problematico.

Se la Pubblicazione dovrebbe essere un oggetto di valore puro, allora dovrebbe essere immutabile. Pertanto, non si dovrebbe essere in grado di creare un inserimento senza designare la stima a cui appartiene. Quindi, ogni volta che c'è bisogno di creare Pubblicazione, c'è anche la necessità di accedere a qualche DebitAccount e alle sue Stime. Sembra un sacco di controllo e la logica sta uscendo dalla classe DebitAccount.

Cosa accadrebbe se solo un account di addebito sapesse come le sue stime e le registrazioni sono correlate tra loro? Quindi non ci sarebbe bisogno di avere un riferimento a una stima da un post e forse nemmeno riferimenti da stima ai post.

Questo risolverebbe i problemi 1 e 2, credo.

Informazioni sul problema 3: probabilmente preferirei avere un metodo AccountService.ExecuteTransaction(Transaction) invece di un metodo DebitAccount.TransferAmountTo(DebitAccount, Amount amount, string transfername) . Una transazione potrebbe essere un oggetto valore come

class Transaction : ValueObject {
    private Id fromAccountId;
    private Id toAccountId;
    private Amount amount;
    private string name;
    ...
}

Il metodo Execute aggiornerebbe quindi entrambi gli account e si assicurerà che tutto venga mantenuto correttamente.

    
risposta data 06.09.2018 - 16:01
fonte

Leggi altre domande sui tag