Responsabilità dell'oggetto strategico / dominio

2

Supponiamo di essere nel mondo della domanda di noleggio auto:)

Diciamo che ho 3 tipi di auto con 2 categorie di prezzo:

Car type         Price category
------------------------------
Sport            High
Luxury           High
Economy          Low

I valori di High e Low possono cambiare nel tempo, quindi dovrebbero essere un'entità separata con una propria rappresentazione in DB.

Ogni tipo di auto ha una propria strategia di calcolo dei prezzi, ad es. noleggiare un Sport costi auto (High x time_rented) + High_constant_factor .

Di seguito è il mio approccio attuale:

  • una strategia / politica di calcolo per tipo di auto. Incapsula il know-how necessario per calcolare il prezzo, con le seguenti responsabilità: determina il fattore costante da utilizzare, preleva il prezzo appropriato da un pronti contro termine e infine calcola il prezzo totale applicando la giusta formula di calcolo. Esempio: SportCarPriceCalculationPolicy utilizza HIGH_CONSTANT_FACTOR codificato e recupera findPrice(Low) .
  • a Car non sa nulla del suo prezzo o constant_factor .

È un buon approccio? O dovrebbe Car essere consapevole del suo prezzo e passare High / Low come argomento a un criterio ed evitare che tale politica abbia alcuna dipendenza dal repository?

    
posta JohnD 10.09.2018 - 13:09
fonte

2 risposte

2

Hai scelto l'approccio giusto.

Strategia e passaggio dei parametri

L'intento del modello di progettazione della strategia è secondo GoG:

define a family of algorithms, encapsulate each of one and make them interchangeable. Strategy lets the algorithm vary independently from the client that uses it.

Il parametro che passa tra la strategia e il suo contesto richiede alcuni compromessi:

  • L'interfaccia per la strategia deve essere comune a tutti gli algoritmi supportati. Quindi, il passaggio solo di alcuni valori limiterà l'evoluzione futura.
  • Passare al contesto (l'auto invocherà la strategia o un contratto di affitto lo invocherà?) è noto per creare un accoppiamento più stretto. Ma aumenta la flessibilità se i parametri devono evolvere
  • Lasciando che la strategia trovi elementi di cui ha bisogno sembra un'opzione ragionevole e lascia la libertà per rendere più complessi gli algoritmi incapsulati.

La scelta delle responsabilità

Nel tuo modello, la strategia è responsabile della ricerca di parametri aggiuntivi. È una scelta valida con i seguenti vantaggi:

  • i dettagli dell'algoritmo e la ricerca di eventuali parametri di calcolo aggiuntivi rimangono nella cucina interna della strategia. Questa è separazione delle preoccupazioni.

  • l'evoluzione degli algoritmi non è limitata a un insieme minimalista di parametri. In particolare, l'interfaccia rimarrà stabile (vale a dire che non deve cambiare ogni volta che si crea un nuovo algoritmo di pricing fantasia).

A proposito, la macchina non può sapere il suo prezzo. Hai spiegato il motivo: il prezzo base cambia frequentemente. Quindi, un'auto ha diversi prezzi. Il giusto prezzo può essere determinato solo in combinazione con una data di noleggio. Quindi il prezzo è qualcosa associato alla macchina. L'unica domanda che rimane è se si tratta di un'entità o di un oggetto valore? (Opterei per il secondo: non ci interessa l'identità di un prezzo: ci prendiamo solo cura del suo valore)

Evoluzione delle strategie di pricing

Garantire che la strategia di pricing possa facilmente evolversi è fondamentale per il tuo design. Si inizia con un modello di determinazione dei prezzi molto semplice. Ma questo potrebbe rapidamente evolversi in qualcosa di più complesso.

Il prezzo dipende più generalmente da 3 diverse categorie di informazioni:

  • Prodotto: cerchi solo la categoria di prezzo. Ma potresti anche voler guardare ad altri attributi del prodotto, come la fresatura, la potenza del motore, il tipo di energia, il marchio.

  • Cliente: lo ignori completamente. Ma potresti volere un giorno concedere alcuni buoni clienti con alcuni vantaggi.

  • Condizioni transazionali: si guarda solo alla quantità e alla data del prezzo. Tuttavia, in futuro, potresti prendere in considerazione anche alcune promozioni speciali per le vacanze, condizioni di pagamento (ad esempio lo sconto per il pagamento anticipato) o criteri geografici.

Inoltre, l'algoritmo di prezzo potrebbe evolvere:

  • al momento utilizzi lo stesso metodo di calcolo, con la strategia che ha limitato solo un impatto limitato influenzando i parametri della formula.
  • ma domani potresti considerare il miliardo e il luogo geografico per le auto di lusso e la potenza del motore per le auto sportive.
  • Potresti anche scegliere diverse formule. Ad esempio degressivo per l'economia, costante per il lusso, progressivo per lo sport.
risposta data 11.09.2018 - 00:41
fonte
1

Offro un approccio diverso, leggermente più DDD, a questa situazione. Piuttosto che concentrarsi su un meccanismo coesivo come PriceCalculationPolicy , lascia che sia un dettaglio di implementazione e concentrati sul modello.

Ciò di cui abbiamo bisogno qui, al fine di rendere esplicito implicito, è un nuovo oggetto dominio che cattura il comportamento / concetto che stiamo ballando intorno. Ciò di cui abbiamo bisogno è un Rental . Un Rental incapsula tutte le informazioni necessarie per soddisfare / tracciare / gestire il processo di noleggio auto e anche calcolare il prezzo.

Al momento, sembra che tu usi solo informazioni come CarType , PriceTier e ExpectedDuration , ma in teoria è possibile aggiungere qualsiasi tipo di dettagli transazionali / informazioni ausiliarie: Date , CustomerAge , CouponCode , ecc.

Così nuovo quando arriva un comando RentCar , l'applicazione può utilizzare le informazioni inviate con il comando ( CarType , CustomerId , ecc.), per creare esplicitamente un nuovo Rental e mantenere le informazioni indietro nel tuo negozio di dati. Utilizzando un "Accumulating Snapshot Table" (o equivalente) nel tuo backing store puoi incorporare metodi come Rental.SelectCar(lotId, carId) e Rental.ReturnCar(lotId) che tracciano il progresso di un Rental durante il suo ciclo di vita.

Per quanto riguarda i prezzi, se hai bisogno di algoritmi diversi piuttosto che di parametri diversi, sei libero di creare diversi tipi di Rentals . Il bit importante qui è, piuttosto che avere tutti questi dati transitoriamente presenti come parte di uno script di comando, per modellare invece il comportamento in modo che possa essere catturato. Lascia che le regole esistano con i dati, NON intorno ai dati.

Il problema con oggetti di dominio come Rule e Policy è che separano dati e comportamenti. Cioè, il tuo Rental diventa semplicemente un sacchetto di dati che viene ispezionato / scricchiolato secondo alcune regole. Separare i dati dal comportamento è un paradigma fondamentalmente procedurale, non OOP, e certamente non DDD. La creazione di un meccanismo coesivo separato per incapsulare la funzionalità algoritmica è più adatta per le situazioni in cui la logica è così dettagliata che il modello inizia a perdere il focus ( (x * y) + z non conta).

    
risposta data 17.10.2018 - 21:00
fonte