Implementazione del Principio di Responsabilità Singola

5

Nel mio tempo libero, ho progettato un CMS per saperne di più sulla progettazione e l'architettura del software, ecc.

Passando attraverso i principi SOLID, ho già notato che idee come "MVC", "DRY" e "KISS", praticamente cadono al loro posto. Detto questo, sto ancora avendo dei problemi nel decidere se una delle due implementazioni è la scelta migliore quando si tratta del Principio di Responsabilità Unica.

Implementazione n. 1:

class User
    getName
    getPassword
    getEmail
    // etc...

class UserManager
    create
    read
    update
    delete

class Session
    start
    stop

class Login
    main

class Logout
    main

class Register
    main

L'idea alla base di questa implementazione è che tutte le azioni basate sull'utente sono separate in classi diverse (creando un caso possibile con il nome appropriato Codice Ravioli ), ma seguire l'SRP in un" tee ", quasi letteralmente.

Ma poi ho pensato che fosse un po 'troppo, e ho avuto questa prossima implementazione

class UserView extends View
    getLogin //Returns the html for the login screen
    getShortLogin //Returns the html for an inline login bar
    getLogout //Returns the html for a logout button
    getRegister //Returns the html for a register page
    // etc... as needed

class UserModel extends DataModel implements IDataModel
    // Implements no new methods yet, outside of the interface methods
    // Haven't figured out anything special to go here at the moment
    // All CRUD operations are handled by DataModel 
    //   through methods implemented by the interface

class UserControl extends Control implements IControl
    login
    logout
    register
    startSession
    stopSession

class User extends DataObject
    getName
    getPassword
    getEmail
    // etc...

Questo è ovviamente ancora molto organizzato e ancora molto "responsabilità unica". La classe User è un oggetto dati in cui posso manipolare i dati e quindi passare a UserModel per salvarlo nel database. Tutto il rendering dei dati dell'utente (ciò che l'utente vedrà) è gestito da UserView e dai suoi metodi, e tutte le azioni dell'utente sono in uno spazio in UserControl (più alcune cose automatizzate richieste dal CMS per mantenere un utente loggato o per assicurarmi che restino fuori.) Personalmente non riesco a pensare a qualcosa di sbagliato in questa implementazione.

Nei miei sentimenti personali sento che entrambi sono effettivamente corretti, ma non posso decidere quale sia più facile da mantenere e prolungare man mano che la vita va avanti (nonostante mi stia appoggiando verso l'implementazione n. 1).

Quindi tu ragazzi? Quali sono le tue opinioni a riguardo? Qual è il migliore? Quali sono le basi (o meno, le sfumature) di quel principio mi sono perso in entrambi i design?

    
posta Mike S 10.11.2011 - 03:46
fonte

3 risposte

5

Ho sempre considerato il principio della singola responsabilità più una filosofia che un principio.

Robert C. Martin (Zio Bob) riafferma il principio di responsabilità singola (collegato al PDF) :

There should never be more than one reason for a class to change

Citato dalla risposta hai ricevuto il tuo post.

Quando proviamo a placare l'SPR, ci concentriamo sull'implementazione piuttosto che sullo scopo.

Errore grave.

La mia comprensione dell'SRP è questa, quando un'aggiunta offusca la responsabilità di un'implementazione, il punto focale dovrebbe essere riconsiderato.

Per me, si tratta esclusivamente delle relazioni tra scopi.

Certo, un utente deve essere autenticato e autorizzato per quanto riguarda le azioni da intraprendere, ma l'autenticazione e l'autorizzazione devono essere separate dall'utente.

Non è che proverai ad autorizzare / autenticare un non utente comunque?

E quindi, dovresti considerare di suddividere l'implementazione quando le responsabilità di una classe superano lo scopo. Dopotutto, anche gli schemi di progettazione hanno scopi.

Dai un'occhiata a GRASP quando ne hai la possibilità.

    
risposta data 10.11.2011 - 10:43
fonte
1

"Principio di singola responsabilità" non è lo stesso di "Principio di funzionalità singola"

Molte volte - quando proviamo a farlo nel modo più religioso possibile - tendiamo a "spezzare" le classi un po 'troppo e possiamo comunque violare SRP in qualche modo perché ora ogni oggetto potrebbe aver bisogno di sapere qualcosa sull'altro che diventa un motivo in più per il cambiamento.

Non sono molto chiaro sull'intenzione delle classi precedenti, ma suppongo che qui ci siano pochi punti -

  • Non so se login e logout possano essere veramente indipendenti l'uno dall'altro e se uno di essi può essere indipendente da session

  • Non so se considereresti login e logout come classi o metodi e perché.

  • Non so se UserManager facendo create è una qualsiasi forma diversa new user()

Credo di aver sbagliato completamente in molte cose perché non ho capito veramente l'intera cosa. Il secondo è un po 'meglio del primo ma potrei comunque sbagliarmi.

Ma questo è esattamente il punto - osservando le classi le intenzioni sono molto chiare - il segno che SRP non sta lavorando proprio qui.

    
risposta data 11.11.2011 - 17:16
fonte
0

Un modo in cui mi piace farlo è iniziare a costruire le tue lezioni ignorando l'intera struttura.

E poi seguire una regola generale di 3.

  • Se ti ritrovano con più di 3 funzioni pubbliche, suddividili in classi separate.
  • Se finisci con più di 3 variabili interne, suddividilo in classi separate.
  • Se ti ritroverai con più di 3 linee funzionali nella tua funzione, separala in diverse funzioni.

In questo modo non devi angustiare se la tua struttura è corretta o meno. Puoi essere fluido con il tuo sviluppo. Questo processo di codifica è più semplice se si hanno test unitari o TDD in generale, ma non è richiesto al 100%. Rimuove anche alcuni sovraccarichi mentali per il tuo cervello.

Trovo che un giorno mi preoccuperò così tanto della struttura e ne agonizzerò così tanto che, col passare del tempo, sono troppo attaccato alla struttura e sono meno disposto ad adattarmi quando ne ho bisogno.

    
risposta data 10.11.2011 - 13:30
fonte

Leggi altre domande sui tag