Il miglior modello di progettazione OOP per una sequenza di operazioni


11

Sto lavorando a un'applicazione, un modulo del quale esegue le seguenti operazioni finanziarie in sequenza:

Quando un utente richiede che un determinato importo venga trasferito sul suo conto bancario:

  1. controlla se qualche transazione può avvenire ora? (la transazione può essere eseguita solo durante un certo periodo di tempo)
  2. verificare se l'utente ha richiesto il prelievo di un importo minimo
  3. controlla se l'utente ha un account predefinito

Il risultato di tutte le azioni sopra riportate deve essere registrato.

Se tutte le condizioni di cui sopra soddisfano, la transazione viene eseguita. In futuro potrebbero esserci ulteriori controlli.

Quale modello di design orientato agli oggetti dovrebbe essere più adatto al caso sopra?


3
Non cercare mai un modello di progettazione per risolvere un problema. Utilizzare i modelli di progettazione per comunicare la soluzione corretta. programmers.stackexchange.com/questions/70877/… Segui i principi SOLID e non sbaglierai molto.
pdr

2
Non sono d'accordo. I modelli hanno nomi che facilitano la comunicazione e dovrebbero anche essere usati per comunicare soluzioni. Ma non sono d'accordo con "Non cercare mai un modello di progettazione per risolvere un problema". Non solo risolvono problemi specifici, ma affrontano anche forze e vincoli diversi. Dai un'occhiata a "Proxy" e "Decorator". Sembrano simili ma risolvono problemi diversi. Quindi, a mio avviso, prima di risolvere un problema da soli, dovresti almeno dare un'occhiata a modelli di progettazione noti per trarre profitto da entrambi, un approccio standard per risolvere un problema e un modo semplice per comunicarlo.
Jonny Dee,

10
Ecco una buona caratterizzazione di cosa sia uno schema: "Essi [schemi] forniscono soluzioni funzionanti, concrete e adattabili ai problemi che si presentano ripetutamente in determinate situazioni durante lo sviluppo del software, dai contesti organizzativi a quelli di programmazione". [POSA5, pag. 30] Quindi, da questo punto di vista, è del tutto chiaro che cercare un modello come soluzione adattabile è un approccio legittimo.
Jonny Dee,

3
Stai chiedendo una costruzione orientata agli oggetti per descrivere la semplice vecchia programmazione procedurale?
mouviciel,

4
Segui il principio KISS. Finora il tuo problema può essere risolto con 3 istruzioni "if" in un singolo metodo. Non cercare di usare un modello di design solo per essere cool. Ogni volta che scrivi una lezione aggiuntiva, pensa sempre: ne ho davvero bisogno?
Eiver

Risposte:


13

Sembra che quello che stai cercando sia una catena di responsabilità . In questo caso potresti avere le seguenti classi:

  • TransactionValidatorBase classe base astratta
  • TransactionTimeValidator
  • TransactionAmountValidator
  • TransactionAccountValidator

Che sono concatenati insieme per applicare qualunque regola tu specifichi.

Furter Reading


11
La mia comprensione è che la catena di responsabilità è più un filtro - cioè andiamo giù per la catena fino a quando non troviamo qualcuno attrezzato per far fronte alla responsabilità, quindi quel "collegamento" gestirà la responsabilità e uscirà. Un difetto in COR in termini pratici è che è difficile fargli restituire un valore, che sembra che potresti aver bisogno di questo.
Amy Blankenship,

Penso che tu possa avere una catena di un livello di R. Non penso davvero che sia difficile restituire un valore da una catena, con un po 'di astrazione. Ad ogni livello sarà richiesto di comunicare aderendo a una determinata interfaccia primitiva e sarà richiesto di accettare input dal basso, dato che tali input sono conformi all'interfaccia primitiva. Quando è necessaria la ricchezza dell'interfaccia tra due livelli Chain che sono accoppiati più intimamente, l'astrazione può essere Poly-morphed per supportarlo.
Andyz Smith,

3

Se la tua sequenza di passaggi sta svolgendo principalmente compiti di convalida (come sembra che tu sia), senza mutare gli input, penserei davvero al modello "Catena di responsabilità", come spiegato nella sua risposta di @pswg

Ma poiché la tua domanda è un po 'più generica, vorrei aggiungere anche "Elaborazione pipeline", poiché con questo, un passaggio produrrebbe un output che diventerebbe l'input per il passaggio successivo (mutando così l'input originale) .

Ecco due articoli a riguardo:
Collezione Pipeline di Martin Fowler
Altre discussioni teoriche sul modello


2

Il modello corretto qui dipende davvero da un contesto. Prima di scegliere uno schema particolare a cui attenermi, cercherò di trovare le risposte a queste domande:

  • È necessario creare diverse combinazioni di (1,2,3) controlli in fase di esecuzione?
  • Hanno bisogno delle stesse variabili per eseguire le loro azioni o sono molto diverse?
  • Quanto devono essere precisi i messaggi di errore?
  • In caso di errore, l'utente riprova sempre dal (1) primo passaggio?
  • Come viene gestita la concorrenza?
  • Ogni metodo aggiunge qualcosa alla richiesta o semplicemente convalida? (dire ID acct predefinito?)

Basandomi su un istinto, li codificherei come semplici metodi con aggregando i parametri per i codici di errore.

public void DoTransaction(IErrorAgregator error, TransactionRequest request)
{
    if(!IsTransactionInCertainTimePeriod(request, error)) return;
    if(!IsTransactionAmountInUserBounds(request, error)) return;
    if(!UserHaveDefaultAccount(request, error)) return;
    bankingTransactor.PerformTransaction(request);
}

Potrebbe essere una buona idea inserire DoTransaction nell'interfaccia "ITransactionValidationStragegy" e creare un super-tipo di livello che conterrà il codice del bollettino di convalida.

Tuttavia, in questo progetto presumo che la logica di validazione sia determinata al momento della compilazione.


0

Mentre i modelli sono già menzionati qui, ti suggerisco di pensare a come vorresti usare lo stesso nella tua applicazione, in base ai framework che stai usando.

Ad esempio, la convalida che vorresti fare, molto probabilmente continuerà a cambiare man mano che il tempo avanza (potresti voler aggiungere una nuova convalida in futuro che limita le transazioni a 10 al giorno). Inoltre, potresti non voler eseguire la convalida prima che il tuo vero servizio aziendale o il codice di integrazione entrino in funzione. Sarebbe positivo se puoi avere le convalide aggiunte come configurabili.

Nel caso in cui si utilizzi Struts, l'utilizzo di intercettori potrebbe essere una buona idea. In caso di primavera, l'iniezione di fagioli come dipendenza ti dà maggiore flessibilità. Il mio suggerimento non è solo quello di guardare i modelli / modi di dire, ma anche il framework che usi per costruire l'applicazione e vedere come puoi adattarti al meglio alle tue esigenze da un punto di vista futuristico.


-2

Secondo la mia comprensione tutto ciò che è richiesto può essere inserito nel modello di comando come di seguito. La progettazione della classe può essere eseguita come di seguito.

interface Transaction{
void performAction();
}

class Banking{

void moneyValidation(){
//Validate Here
}

void timeValidation(){
//validate Here
}
}

class TimeValidation implements Transaction{

public Banking bank;

public TimeValidation (Banking bnk){
bank=bnk;
}

void performAction(){
bnk.timeValidation();
}


class MoneyValidation Implements Transaction{

public Banking bank;

public MoneyValidation(Banking bnk;){
bank=bnk;
}

void performAction(){
bnk.moneyValidation();
}
}


class Control{

private List val_list=new ArrayList();

void storeValidation(Transaction trans){
val_list.add(trans);
trans.performAction(val_list.getFirstAndRemove());
}
}

//Same for other validation classes

La tua classe Client conterrà il seguente frammento di codice:

Banking bnk = new Banking();
MoneyValidation m_val = new MoneyValidation (bnk);
TimeValidation t_val = new TimeValidation (bnk);
Control ctrl = new Control();
ctrl.storeValidation(m_val);
ctrl.storeValidation(t_val);

Questo è secondo la mia comprensione, con lo scenario che è stato dato sopra.


È un male perché quando la validazione del denaro fallisce, la validazione del tempo è inutile ma sarà comunque fatta
Ewoks,
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.