Pratiche per incapsulare le raccolte in radici aggregate

1

Come dovrebbero essere esattamente i metodi AddSomething nelle radici aggregate? Devo costruire gli oggetti in una chiamata al metodo, o dovrebbero essere costruiti all'interno del metodo?:

Ad esempio:

public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1) (tratto da qui ).

Versus:

public void AddOrderItem(OrderItem orderItem)

Vedo il secondo schema più comunemente e mi chiedo quando preferire uno rispetto all'altro.

    
posta Konrad 14.08.2018 - 13:46
fonte

2 risposte

3

I wonder when should I prefer one over another.

Ci sono due diverse tensioni al lavoro.

Una di queste è ossessione primitiva

Primitive Obsession is using primitive data types to represent domain ideas. For example, we use a String to represent a message, an Integer to represent an amount of money, or a Struct/Dictionary/Hash to represent a specific object.

Una ragione è una cattiva idea: la logica per valutare i vincoli sui dati sparsi nell'applicazione. Se abbiamo bisogno di un prezzo unitario valido, allora preferiamo verificarne la validità in un unico posto e fare affidamento sul sistema dei tipi per dimostrare che i controlli di convalida sono già stati applicati.

Una famiglia abbastanza comune di errori del programmatore può essere scoperta in anticipo utilizzando questo approccio.

L'altro è boundaries

At the Boundaries, Applications are Not Object-Oriented

I dati devono provenire da qualche parte, e per la maggior parte ciò significa byte , che possono essere interpretati come primitive agnostiche del dominio.

E questo tende ad essere vero per lavorare in entrambe le direzioni attraverso il confine - il nostro input arriva come byte, il nostro output parte come byte.

E quindi devi pensare: sono le radici aggregate parte del confine , o sono all'interno del confine.

Nella maggior parte dei casi in cui la modellazione del dominio ha senso, stai cercando di esprimere la semantica del tuo dominio. Quindi non vuoi che quella logica venga oscurata da una serie di validazioni accessorie. Vogliamo i problemi di dominio isolati dall'impianto idraulico digitale.

In breve

when should I prefer one over another?

Una volta raggiunto il punto in cui lavorare con le primitive è scomodo e senti la necessità di creare un tipo OrderItem , dovresti cercare di deprecare l'interfaccia primitiva

[Obsolete]
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
    AddOrderItem(
        OrderItem.from(productId, productName, unitPrice, ...);
    );
}

public void AddOrderItem(OrderItem orderItem) {
    // pure business logic here
}

Vedi anche: Dall'ossessione primitiva alla modellazione del dominio .

    
risposta data 14.08.2018 - 15:27
fonte
2

Entrambi sono OK, dipende dal contesto.

Puoi usare il primo (quello con i parametri primitivi), se non c'è un vero "comportamento" (cioè la funzionalità aziendale) da legare a quei parametri. Per essere onesti, molto spesso, ci sono almeno alcune funzionalità che puoi associare a questi molti parametri, ma non sempre. Se non puoi, allora va bene enumerarli come tipi primitivi.

Il secondo (quando crei un oggetto per loro) è quando c'è una funzionalità che vorresti usare associata a questi parametri. Mi piace calculateTotalPrice() o qualsiasi altra cosa.

La cosa peggiore che puoi fare è semplicemente "raggruppare" i valori primitivi in un oggetto dati (a volte chiamati "oggetti valore"), che non hanno alcuna funzione, solo i getter per i dati.

    
risposta data 14.08.2018 - 15:44
fonte

Leggi altre domande sui tag