Domanda

Ho una classe "Ordine d'acquisto". Contiene informazioni su un singolo ordine di acquisto. Ho una classe DAO per i metodi di database.

Dove dovrebbe risiedere la responsabilità per i metodi che caricheranno e aggiorneranno l'ordine di acquisto?

Se la classe PurchaseOrder dovrebbe avere '.update', 'insert', 'delete' e '.load' metodi che usano direttamente la classe DAO, o se la classe PurchaseOrder dovrebbe ignorare i metodi DAO e avere una classe POController che gestisce queste interazioni?

L'utente lavorerà su un singolo OrderOrder alla volta.

Grazie!

È stato utile?

Soluzione

L'ordine di acquisto deve essere ignaro dei dettagli della sua persistenza. Questo è il punto di avere una sorta di livello di accesso ai dati, gestisce la gestione dell'oggetto e l'oggetto stesso può concentrarsi sul solo essere un ordine di acquisto.

Ciò semplifica anche il test del sistema, in quanto è possibile creare ordini di acquisto fittizi e testare la logica di come il sistema li gestisce senza rimanere impigliati in problemi di persistenza.

Altri suggerimenti

Vorrei renderlo semplice trasformando OrderOrder in un'interfaccia e inserendo tutto il codice DAO nell'implementazione, quindi utilizzare una factory.

Dipende da quanto pensi che la tua applicazione rimarrà in vigore. L'applicazione di taglio dei metalli della mia azienda è stata continuamente sviluppata dal 1985 ed è stata oggetto di numerosi cambiamenti nelle architetture dei computer. Nel nostro caso, spingiamo quasi sempre le cose dietro un'interfaccia (o una classe di controller usando i tuoi termini) perché non vogliamo quello che sarà lo stato delle cose tra 5, 10, 15 anni lungo la linea.

Utilizzando una classe controller possiamo modificare le API sottostanti senza alterare i livelli di logica aziendale e le modifiche dell'interfaccia utente sopra. Questi livelli rappresentano anni di lavoro, quindi è importante preservare il loro comportamento.

Ricorda che la maggior parte della vita del tuo progetto sarà in manutenzione. Qualunque cosa tu faccia ora per rendere più semplice cambiare il design in seguito, pagherai in enormi risparmi di tempo lungo la strada.

La classe PurchaseOrder dovrebbe ignorare il DAO. La classe purchaseOrder dovrebbe rappresentare i dati stessi e nient'altro. Utilizzare un controller o un gestore servizi o come si desidera chiamarlo per persistere / caricare i record di OrderOrder utilizzando DAO. Questo ti dà la massima flessibilità nel tuo design. Hai un posto per il tuo modello di dati, un posto per la tua logica aziendale (il responsabile del trattamento) su come gli ordini di acquisto vengono archiviati / recuperati e un posto dove sono effettivamente persistiti.

Lascia che ti accompagni nel mio ragionamento:

Metodi di classe
Principio di base: La persistenza è un comportamento di classe e dovrebbe essere un metodo di classe
È necessario separare le preoccupazioni, quindi si inserisce il database in una classe DAO e lo si utilizza dalla classe per implementare i metodi.
Primo problema: se devi supportare diversi set di DAO devi crearli attraverso una Factory. Secondo problema: non tutti i comportamenti di persistenza sono specificamente correlati a un'istanza della classe. Ad esempio i metodi Elenco e Ricerca: restituiscono elenchi di classi, non classi, e non dipendono da un'istanza. Quindi sono fondamentalmente metodi statici .
Terzo problema: si desidera supportare l'ereditarietà in questa classe. Pertanto, i dettagli di persistenza differiscono da genitore a figlio. Se hai metodi statici, sarà un problema.

Quindi passi al

Regolatore
Principio di base: I metodi di persistenza non appartengono a una singola classe, sono più grandi e quindi dovrebbero essere separati
La separazione delle preoccupazioni è di nuovo necessaria, quindi sono necessari DAO. Questa è una classe Utility quindi i metodi sono sostanzialmente statici .
Primo problema: è necessario un Factory per creare i DAO se si desidera supportare più di un metodo di persistenza.
Secondo problema: si desidera supportare una gerarchia di classi in modo da non poter utilizzare una classe statica. È necessario generare i controller attraverso una fabbrica.
Terzo problema: stai offrendo un'API complicata ai tuoi sviluppatori.
Esempio di codice client:

PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);

quindi vorrei iniziare da zero.

Inizia dai comportamenti
Principio di base: La persistenza non è un comportamento. I comportamenti sono più grandi della persistenza.
Nel tuo sistema ci sarà un sottosistema Ordine d'acquisto. Il tuo utente sarà in grado di interagire con esso solo ad alto livello (utilizzare il livello del caso). Pertanto, i metodi implementeranno i casi d'uso dell'Ordine di acquisto. Questi metodi useranno i DAO, attraverso una fabbrica, se necessario, per accedere al database e fare tutto ciò che devono fare.
In breve, il tuo OrderOrder è fondamentalmente un DTO, un modo rapido per trasferire i dati. Non dovrebbe avere comportamenti.
Esempio di codice client:

// It could be a factory if needed.
PurchaseOrderSystem pos = new PurchaseOrderSystem(); 

List<PurchaseOrder> transacted;
transacted = pos.TransactPurchaseOrders(john, 23);

// Show transacted purchase orders or whatever...

Separerei definitivamente la "logica di business" (PurchaseOrder) dall'interazione / accesso al database. Se si sposta a un altro fornitore, ecc., Sarà più facile apportare modifiche all'accesso senza interferire potenzialmente con l'implementazione aziendale, inoltre sarà più facile evitare di aggiungere comportamenti al livello di accesso al database.

Personalmente, creerei un oggetto che gestisce le interazioni. Non posso fare una buona ragione per NON mettere questa logica nella stessa classe OrderOrder, ma la creazione di questo oggetto controller porterebbe a oggetti più liberamente accoppiati.

La cosa chiave a cui pensare qui è cosa potresti voler fare in futuro. Forse vuoi sostituire il tuo database con un altro? Ecco perché dovresti assolutamente separare il tuo codice per l'interazione con il database dalla classe che rappresenta il PO. Questa è la separazione di base della responsabilità e spero che tu l'abbia già fatto.

Ora la domanda è: vuoi una terza classe (controller) per gestire l'interazione tra le classi PO e DAO? Penso che dipenda da quanto in generale puoi rendere l'interfaccia alla classe DAO. Se l'interfaccia DAO è abbastanza generica da poter scrivere una sostituzione plug-in per essa utilizzando un meccanismo di archiviazione diverso ma senza modificare l'interfaccia, allora lascerei che la classe PO interagisca con essa. Altrimenti scriverei una classe controller.

L'altra cosa a cui pensare è il resto della struttura. Da dove viene avviato il salvataggio / caricamento? Se hai intenzione di fare molte manipolazioni del PO (salvataggio, caricamento, stampa, invio al cliente), probabilmente ha senso avere un controller che fa tutte queste cose piuttosto che integrare la funzionalità nella classe PO . Ti dà il vantaggio di poter aggiungere operazioni PO senza dover modificare la classe PO.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top