Esiste un modello di progettazione che si applicherebbe ai modelli di sconto?


35

Esistono modelli di progettazione noti per l'implementazione di modelli di sconto?

Per modelli di sconto, intendo quanto segue:

  1. Se un cliente acquista il Prodotto X, il Prodotto Y e il Prodotto Z, ottiene uno sconto del 10% o $ 100.

  2. Se un cliente acquista 100 unità del Prodotto X, ottiene uno sconto del 15% o $ 500

  3. Se un cliente ha portato nell'ultimo anno oltre $ 100.000, ottiene uno sconto del 20%

  4. Se un cliente ha acquistato 2 unità di Prodotto X, ottiene 1 unità di Prodotto X (o Prodotto Y) gratuitamente.

  5. ...

Esiste un modello generico che può essere applicato per gestire tutti gli scenari di cui sopra? Sto pensando ad alcuni modelli, ma non riesco a trovarne uno generico.


IIRC tutti i tutorial che ho visto con esempi di sconti (ce ne sono molti) suggeriscono un modello di strategia
moscerino del

2
@Kanini È un problema del mondo reale? In tal caso, questo sistema è in tempo reale o differito? Queste regole sono presentate come un motore di regole o valori di database? La ricerca di sconti è gerarchica in base alla priorità? Il modello di strategia funzionerebbe nella maggior parte dei casi, ma le regole devono essere prese in considerazione per farlo funzionare
Ubermensch,

3
Inoltre, se qualcuno acquista 2 unità di Prodotto X, un Prodotto Y e un Prodotto Z, otterrebbe sia il 10% che un ulteriore prodotto X?
Ubermensch,

@gnat alcuni link ad alcuni di questi tutorial per favore.
user16764

Risposte:


18

Se il problema è che è necessario applicare più sconti, in determinate circostanze, è possibile prendere in considerazione il modello di catena di responsabilità .

In poche parole, si passano le informazioni che si desidera elaborare nel primo processore e decide da lì se passarle a ulteriori processori prima di restituire il risultato.

In questo modo è possibile modificare la struttura e la sequenza dei processori senza mai modificare il codice chiamante.


La catena di responsabilità è un'altra buona. Potrebbe anche essere associato a una strategia. Nel caso in cui sia possibile applicare solo uno sconto, ogni strategia è concatenata a un'altra. Ogni catena calcola il suo sconto (se il cliente è idoneo), lo confronta con lo sconto precedente e passa i dati del cliente, dell'ordine e dello sconto alla catena successiva. +1.
Thomas Owens

1
Solo la mia opinione, ma trovo più probabile che "Chain of Responsibility" stia progettando troppo per questo caso. Un semplice elenco di modelli di sconto (se necessario, con un numero d'ordine) dovrebbe farlo. L'elenco stesso è indipendente dal cliente e dai suoi ordini, poiché tutti i clienti devono essere trattati allo stesso modo. La "catena di responsabilità" è più appropriata quando l'elenco dei modelli di sconto cambia molto frequentemente in fase di esecuzione in modo altamente dinamico.
Doc Brown,

11

I modelli di strategia, decoratore e stato si distinguono per me come potenziali punti di partenza. Lo stato può essere particolarmente utile per 2 o 3, poiché 2 dipende dallo stato dell'ordine e 3 dipende dallo stato del cliente entro un periodo di tempo. Strategia e Decorator si distinguono per gli altri, poiché è possibile utilizzare la strategia per implementare più algoritmi di calcolo del prezzo dell'ordine e decoratore per aggiungere nuovi sconti all'ordine.

Tuttavia, ricorda che i modelli di progettazione sono solo modelli. Potrebbe non esserci un unico schema applicabile, ma piuttosto un sistema di schemi. Considera anche di apportare modifiche ai modelli descritti per adattarli meglio alla tua soluzione. È meglio avere un buon design piuttosto che forzare un modello in cui non è necessariamente utile solo per il gusto di poter dire che hai un modello.


Non è proprio quello che il modello di stato intende fare, vero?
pdr

@pdr Non vedo perché no. Ma dipende dalla tua implementazione. Se l'oggetto del cliente tiene traccia degli sconti dipendenti dal cliente, potrebbe esserci un'operazione per restituire gli sconti per i quali il cliente è idoneo. Man mano che il cliente acquista cose, gli attributi cambiano e l'implementazione di questo metodo cambia tramite il modello di stato.
Thomas Owens

1
Capisco cosa intendi. Penso che dipenda se il cliente è un oggetto semi-permanente nell'applicazione o solo qualcosa che vive nel database e deve essere aggiornato. Non è chiaro dalla domanda, quindi abbastanza giusto. +1
pdr

3
In base alle mie esperienze, questi tipi di regole commerciali scontate vengono continuamente modificate dai dipartimenti di marketing / vendita volubili. Vi è una grande necessità di renderli guidati dai dati e modificabili dall'utente piuttosto che interamente guidati dal codice. In che modo ciò influenzerebbe la scelta del modello?
jfrankcarr,

@jfrankcarr Nella mia mente, non lo sarebbe. Popolerei i valori per insiemi di articoli che portano a uno sconto, le percentuali di sconto e così via da un qualche tipo di configurazione. Una specie di costruzione dinamica delle transizioni della mia macchina di stato e degli attributi dei miei decoratori e strategie.
Thomas Owens

10

Bene, progetterei un modello di sconto come coppia "Precondizione" e "Sconto", dove "Precondizione" è una classe con metodi

  bool IsFulfilled(Customer c);

o / e

  bool IsFulfilled(Customer c, Order o);

e lo sconto ha un metodo void ApplyTo(Customer c). Questo ti dà la possibilità di combinare qualsiasi tipo di precondizione con qualsiasi tipo di sconto (penso che questa sia una forma di "schema a ponte").

Se si dispone di un numero fisso di condizioni preliminari, è possibile risolvere il problema creando sottotipi specifici (modello di strategia). Tuttavia, quando le tue condizioni preliminari possono essere molto complesse, con istruzioni logiche come AND, OR e NOT, potresti implementare meglio un qualche tipo di interprete di regole per le condizioni. Le regole possono essere una stringa di testo semplice scritta in un semplice "linguaggio specifico del dominio".

Lo stesso vale per la classe "Sconto", è possibile avere alcuni sottotipi per diversi tipi di sconti o un approccio generale in cui le regole di sconto sono fornite in forma testuale, valutate da un interprete.


La mia intuizione suggerisce che questo potrebbe essere quello che sta cercando nel contesto della domanda
Ubermensch,

4
  • Probabilmente è necessaria un'interfaccia IDiscount in quanto tutti i diversi sconti sono la stessa cosa e vorremmo gestirli concettualmente come sconti generici.

  • La classe "questo ordine cliente" ha probabilmente bisogno di una raccolta di sconti. Elenco? Hash? Lista collegata? Non importa, ancora. Gli sconti si applicano all'acquisto, non al cliente!

  • Mantieni la creazione dell'istanza di Discount separata dal Cliente, dal Carrello, dalla Cronologia, ecc. Cambierà molto, come sottolineato da @jfrankcarr.

  • Probabilmente una classe diversa per ogni sconto in quanto l'algoritmo e i parametri per ogni sconto variano in modo selvaggio e imprevedibile.

  • Vedo molta gestione degli eventi poiché il calcolo dello sconto risponde alle modifiche del carrello e viceversa.

Applicazione del modello di progettazione

  • Vedo a strategy pattern. IDiscount è l'interfaccia per l'implementazione di diversi algoritmi di sconto.
  • Vedo a factory. Certamente non una vera e propria abstract factory pattern, ma una singola classe a questo punto dell'analisi. Ragionevolmente, ci deve essere un unico posto in cui esiste un contesto sufficiente per decidere quali sconti applicare e quindi crearli. Una classe. Se le regole per l'applicazione degli sconti in seguito esplodono a causa di una festa di funghi del dipartimento marketing, qualsiasi ulteriore logica di costruzione degli sconti deve ancora fondersi in questa classe di fabbrica di base, penso.

  • Posso vedere Chain of Responsibility. Questo non si esclude a vicenda factoryall'idea. Invece di ripetere una raccolta di sconti, ogni sconto chiama il ragazzo successivo. La classe "ordine del cliente" non contiene una raccolta di sconti in questo caso.

  • Il fattore "hmmmm ...." in Chain of Responsibility, penso, è che ogni sconto ha un riferimento al successivo. L'implicazione è che l'ordine conta. Non è così. Inoltre, il concetto che il CdR incarna è che un oggetto non può gestire la richiesta, quindi viene passata "alla successiva autorità superiore". Il nostro modello è diverso. L'unica richiesta è di calcolare. Ogni sconto fa questo. L'output o l'effetto possono essere nulli ma viene calcolato ogni sconto. Istintivamente mi sposto verso una fedeltà del mondo reale superiore.

ipotesi

  • Gli sconti si basano sul carrello della spesa corrente e / o sulla cronologia degli acquisti
  • Potrebbero essere applicati zero o più sconti. Non ci sono sconti reciprocamente esclusivi
  • Il corretto calcolo non dipende dall'ordine in cui vengono applicati gli sconti.

Cosa cambia, cosa rimane uguale?

  • Gli sconti sono molto diversi. Numero e tipo di parametri diversi per comporre ciascuna regola.

  • Gli argomenti per gli sconti idonei cambiano al variare del carrello.

  • Il numero di sconti disponibili cambia

  • Gli sconti che questo cliente si qualifica per le modifiche man mano che il suo carrello cambia.

  • La cronologia degli acquisti non cambia nel contesto di questo acquisto

  • Il costo totale cambia dinamicamente in funzione delle linee di acquisto e degli sconti applicati.

  • Dopo l'applicazione iniziale, l'output di uno sconto può cambiare, come ad esempio la quantità di acquisto cambia.


Ottima e completa risposta ... MA ho solo una preoccupazione ed è che la sezione delle ipotesi non dovrebbe essere lì, almeno non per guidare la risposta. L'idea è che il modello aiuta a dare esattamente conforto e dimenticare i "presupposti", la regola generica non ha bisogno di sapere come vengono eseguiti i calcoli e quali usi dettagliati dell'implementazione dal contesto (Cliente, Articoli carrello , Giorno, Stagione, ecc.). Davvero un aiuto completo
le0diaz,

I punti elenco in primo piano e la sezione "Presupposti" sono solo il mio ragionamento "mostra il tuo lavoro" sul problema stesso che ovviamente ha un bering sul design del modello di sconto. Ad esempio, i miei presupposti sull'ordine di esecuzione degli sconti e l'interdipendenza mi portano a de-enfatizzare la catena di responsabilità. Nota che sto pensando all'intento del modello, non alla complessità come fa @docbrown. Sono un sostenitore esuberante per riflettere l'intento nel design.
radarbob

1

Logicamente, un modello di sconto può essere qualsiasi cosa , quindi non puoi presumere che puoi programmare tutti i casi in anticipo. Né chiunque può rispondere alla tua domanda può essere completamente sicuro di ciò di cui hai effettivamente bisogno. Tuttavia, supponendo che tu ottenga i soliti tipi di sconti trovati nel mondo reale ...

Una grande domanda è se gli sconti saranno programmati o se si desidera che gli utenti li inseriscano. Come accennato in precedenza, non è mai possibile programmarli, ma di solito l'obiettivo è quello di provare a renderlo più immissione di dati come per i casi comuni, piuttosto che programmarli tutti. Ciò si applica in una certa misura anche se i programmatori vengono utilizzati per creare tutti gli sconti.

Martin Fowler menziona "Metodo di istanza individuale" in "Modelli di analisi: modelli di oggetti riutilizzabili" come parte di come implementare le "Regole di registrazione" per i sistemi contabili, ma le regole sembrano abbastanza simili alle tue. Darei maggiori dettagli ma è un'opera protetta da copyright e

Per un'interfaccia utente, è necessario elaborare casi d'uso abbastanza semplici oppure creare un interprete e un generatore di query. Forse entrambi, uno per casi semplici e uno più avanzato. Se scrivi un interprete, questo è probabilmente un buon caso per usare il modello Interprete, poiché è relativamente semplice da programmare rispetto a un generatore di parser, e il tempo di analisi più lento probabilmente non importerà davvero. (Se ti piace usare i generatori di parser non lasciarmi fermare).

Tuttavia, non provare a fare tutto con un interprete - a un certo punto stai solo programmando nel tuo linguaggio scadente, quindi potresti anche usarne uno vero. Se il tuo linguaggio interpretato supporta funzioni (probabilmente dovrebbe supportare chiamarle - definirle è dubbio) quelle possono essere codificate in un linguaggio reale. Non andare più avanti di questa strada di quanto tu debba fare.

Indipendentemente da ciò che fai, alla fine qualcuno vorrà che lo sconto si basi sul fatto che abbia acquistato entro 30 giorni lavorativi da una promozione - dove i giorni lavorativi contano solo se non ci sono vacanze nella regione definite dal codice postale del negozio o dal cliente codice postale. Quindi non provare a progettare il sistema perfetto in anticipo - supponi che a volte dovrai scrivere codice per nuovi tipi di sconti e progettare di conseguenza.


0

C'è qualche punto è chiedersi se esiste un modello utile per questo? Che tipo di modello è richiesto - strutturale o comportamentale?

Idealmente, se dovessi scrivere un software per questo, basterà un algoritmo . Una semplice funzione che calcola lo sconto totale come segue:

cart.calculateDiscount(productVector);

Non hai assolutamente bisogno di altro!

Per chiarire: capisco che ci saranno molte regole - la maggior parte di tali rappresentazioni dovrebbe essere sotto forma di una base di regole (insieme di attributi di dati e sconto risultante contro di esso) e la funzione come sopra lo ripeterebbe per calcolarlo. Se le regole vengono aggiunte o rimosse non dovresti finire per cambiare il codice, basta cambiare la rule base.

Il modello sarà richiesto solo se abbiamo bisogno di oggetti diversi per accedere alle API l'uno dell'altro o comunicare per mettere in atto un'attività.

PS: pensaci - quando il firewall elabora i pacchetti e passa o rifiuta i pacchetti (o li modifica) - quale modello di progettazione utilizza? La risposta è NESSUNO di quanto sopra descritto!


Certo, hai bisogno di qualcosa di più !!! L'idea è che l'algoritmo non sia strettamente associato all'implementazione del codice. Se controlli che gli scenari sono altamente probabili che ne verranno fuori altri, anche se in qualche modo lo hai menzionato, non ha davvero da cosa dipenderà qualsiasi altra "Regola". È ingenuo pensare che una regola dipenderà solo dall'elenco dei prodotti, ma in realtà dipende dal cliente, dal tempo, dalla stagione e così via. Non so quale implementazione di Firewall hai controllato, ma quelli che ho controllato
POSSONO avere
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.