Come creo un livello aziendale semplice ma complesso?

0

Sto lavorando con un'applicazione web abbastanza complessa. È suddiviso nei seguenti livelli:

  • Presentazione - HTML
  • Livello di servizio: API REST e SOAP in comunicazione con il livello aziendale
  • Livello aziendale: contiene la logica aziendale.
  • Accesso ai dati: fornisce accesso allo spazio di archiviazione (SQL ecc.)

I livelli aziendali contengono classi che incapsulano aree specifiche, come la registrazione dei clienti, la gestione degli utenti e altro ancora. Il problema che stiamo vedendo è che il livello aziendale inizia a diventare un po 'disordinato. Abbiamo un'unica classe che gestisce la gestione dei clienti, ma man mano che quest'area dell'applicazione diventa sempre più complessa, la classe cresce, cresce e diventa disordinata.

Ad esempio, potremmo avere le seguenti classi

  • class CustomerManager

    • void CreateCustomer (...)
    • void DeleteCustomer (...)
  • class UserManager

    • void CreateUser (..)
    • void DeleteUser (...)
    • void ActivateUser (...)
    • void InactivateUser (...)
    • void ResetPassword (...)

La creazione di un cliente comporta anche la creazione di utenti. Quindi, CustomerManager chiama i metodi misc nella classe UserManager. Con l'evolversi dell'applicazione, la creazione di un nuovo cliente implica circa 10 operazioni diverse, ad eccezione della registrazione del cliente nel database, come l'informazione sulle vendite, la registrazione degli audit, la configurazione degli account utente predefiniti, la creazione di una configurazione predefinita per il cliente, la notifica utenti finali delle loro password generate automaticamente e altro ancora. Quindi CustomerManager.CreateCustomer cresce fino a ~ 100 linee di codice piuttosto peloso.

Sto cercando di pensare a un buon modo per gestirlo, ma presumo che ci sia un modo comune per farlo, di cui non sono a conoscenza.

Ho preso in considerazione la creazione di classi "Task" / "Command" che implementano piccoli sottoprocessi e quindi consentono a CustomerCreation.CreateCustomer di eseguire semplicemente una serie di attività. Avrei più lezioni ma farebbero ognuna meno cose.

Ho anche preso in considerazione l'implementazione di alcuni tipi di sistemi di eventi / plug-in a livello di applicazione globale in cui CustomerManager.CreateCustomer crea semplicemente il cliente nel database e quindi pubblica un evento creato dal cliente. I plug-in / qualcosa possono quindi iscriversi a questi eventi e fare cose come informare le vendite e registrare il fatto. Usando questo metodo, non dovrei effettivamente aggiornare CustomerManager.CreateCustomer quando voglio fare più cose che è qualcosa che mi sembra attraente.

Quale modello di progettazione ovvio mi manca?

    
posta Nitra 14.09.2013 - 15:57
fonte

3 risposte

1

I plugin sono utili se vuoi consentire a terze parti di estendere la tua attuale applicazione, ma in caso contrario, rischi di rendere l'architettura più complessa del necessario.

Fai un favore a te stesso e prima di provare a lanciare casualmente alcuni pattern sul tuo livello aziendale, inizia con cose piccole e semplici per primi :

  • se hai un metodo con 100 linee di codice, avvia il refactoring su molti metodi più piccoli.
  • assicurati che i tuoi metodi più piccoli abbiano tutte una singola responsabilità (vedi anche: SOLID ), e prova a raggiungere uno stato in cui le parti dei metodi di chiamata funzionano tutte allo stesso livello di astrazione
  • quando hai abbastanza piccoli metodi che trattano un argomento specifico, puoi estrarli in classi (specialmente quando i metodi più piccoli condividono esclusivamente alcuni dati)
  • puoi avere in mente il modello "comando" per le nuove classi che crei. Se è davvero una buona idea usare quel pattern lo si rivelerà dopo aver creato alcune di quelle classi di helper e sembreranno tutti simili a comandi simili, con un'interfaccia simile a comandi
risposta data 14.09.2013 - 16:37
fonte
1

Come detto @DocBrown, i plugin sono utili soprattutto quando si desidera consentire a terze parti di estendere la propria applicazione. Ma ciò non significa che non puoi usare tecniche simili nella tua progettazione come ciò che viene comunemente usato quando si interfaccia con plugin.

Ad esempio, se gran parte del codice che hai è sulla falsariga di "dopo aver creato il cliente nel database, i componenti X, Y e Z devono essere informati in modo che possano intraprendere le azioni appropriate", quindi puoi usa il pattern Observer per disaccoppiare CustomerRegistration da X, Y e Z (e in un secondo momento, A e B potrebbero anche essere aggiunti a quell'elenco).

D'altra parte, se la tua logica ha un sacco di ifs , buts e a meno che non ci siano test in essa, allora non c'è modo per ridurre la complessità del codice, perché è inerente alle regole aziendali rappresentate dal codice.

    
risposta data 14.09.2013 - 16:46
fonte
1

L'architettura dei componenti può fornire buoni strumenti per combattere la complessità del livello aziendale. Ad esempio, le notifiche possono essere fatte con la registrazione di abbonati (gestori di eventi). Un sacco di logica può essere fatto dagli adattatori, che forniranno determinate interfacce specifiche alle interfacce utente e cliente. In questo modo la logica può essere disaccoppiata, rendendo superflue grandi classi monolitiche. Speriamo che la tua piattaforma abbia già una collaudata architettura di componenti che puoi utilizzare, il che è molto meglio che implementare "plug-in" da zero.

Risposta precedente (vedere il primo commento):

My first impression of having CustomerRegistration and UserRegistration classes with the methods mentioned is that OO analysis has not been properly accomplished. I always thought that having sensible entities at business layer is the only way to prevent the mess. My advice would be to redesign (if it is not late yet) the business layer classes to better reflect business entities and not frontend processes. It may well be, that after such a redesign complexity will be a fraction of what you have now, and, more important, natural representation of the problem domain will answer your goals better than classes, combined with seemingly related functions.

For example, even as such, UserRegistration should not have DeleteUser method! The task naturally belong to UsersManager class or maybe UserRegistry, if you wish.

In short, I think the problem is that classes are formed around action-like entities, which requires much more interconnections (=mess) than class system around (say) User, Customer, and Managers of those two (managers are more like containers).

There is little point of making User Management OOA from scratch. Good examples can be found from many frameworks, and sometimes they handle much more complex things, like fine-grained authorization, role/permission management, group management, etc.

    
risposta data 14.09.2013 - 17:06
fonte

Leggi altre domande sui tag