Principio di responsabilità singola VS principio di KISS

1

Supponiamo la modellazione del modello User in un contesto di un social network.

Il concetto di utente è composto da due nozioni:

  • Elementi di autenticazione come userName / Password / Email ecc ...
  • Informazioni aggiuntive sui dati a volte denominate "Profilo utente" come firstName, compleanno, immagini ecc.

A prima vista, questa analisi implica la separazione di compiti / responsabilità se vogliamo mantenere SRP.

Tuttavia, tipicamente nel caso di un social network, userName può essere visto come una pura informazione appartenente al profilo di un utente piuttosto che un puro elemento di autenticazione.

Quindi, secondo me, ci sono tre modi per modellare il concetto User .

In primo luogo, l'intero in una classe:
User (userName, password, email, firstName, compleanno, immagine ecc ...)

In secondo luogo, una relazione uno-a-uno tra User e UserProfile :
User (userName, password, email) UserProfile (firstName, birthday, picture etc ...)

Terzo, uno a uno, ma con una ridondanza dei campi comuni (essendo focalizzato sull'autenticazione come informazione utente visibile sul sito Web):
User (userName, password, email)
UserProfile (userName, firstName, birthday, picture etc ...)

Perché la ripetizione qui? Ovviamente per la fiducia e allo stesso tempo evitare i join nei casi di database relazionale quando si desidera recuperare i dati di ciascun profilo di Use.

Che cosa è una buona pratica per modellare questi due concetti? Dove posizionare il campo userName ?

Dilemma being: mantenere KISS (Keep it simple stupid!) o SRP;)

    
posta Mik378 17.05.2013 - 17:02
fonte

2 risposte

5

IMO questa è una falsa dicotomia. Se segui SRP, mantieni il tuo sistema semplice nel complesso. Molteplici classi piccole tendono ad essere più "semplici" (in molti casi) piuttosto che meno grandi classi. Inoltre sembra che tu stia combinando due problemi: come progetti le tue classi e come progetta il tuo database. I due non hanno bisogno di essere correlati.

Nel tuo caso specifico, sembra che tu abbia probabilmente 3 classi: User (nome utente, password, email), UserProfile (nome, compleanno, ecc.) e UserPictures (le immagini, perché perché sarebbero parte del "profilo"?). Quindi puoi creare la tua classe User per includere (tramite composizione) gli altri due.

Naturalmente, questo è solo un tentativo approssimativo di progettazione senza una visione generale più ampia dei requisiti. Esistono molti modi validi, semplici e SRP per abbattere le classi in base alle reali esigenze. Il punto principale è che KISS e SRP non sono intrinsecamente in disaccordo.

Modificato molto più tardi dopo aver imparato di più:

Quando ho scritto questa risposta, stavo pensando all'SRP in termini di "una classe dovrebbe avere una sola responsabilità" che ha molto a che fare con la coesione e l'accoppiamento. Questo è buono, ma da allora ho imparato di più su cosa sia veramente SRP.

Il libro Clean Architecture ha una buona descrizione di SRP (e di tutto SOLID e altro). Originariamente la definizione era "un modulo dovrebbe avere una, e solo una, ragione per cambiare". Ma lo zio Bob lo ha rivisto come "un modulo dovrebbe essere responsabile di uno, e solo uno, attore". Quindi si tratta più dei casi d'uso del perché una determinata persona potrebbe desiderare che le cose cambino.

Per legare questo all'OP, le classi che controllano i comportamenti per cose come password, compleanno e immagini potrebbero essere tutte responsabili di diversi attori. Il tuo team di sicurezza si prende cura delle password e potrebbe farti cambiare questi comportamenti separatamente dai product manager che desiderano modificare il modo in cui i compleanni vengono gestiti. Quindi, per seguire SRP, sarebbe opportuno capire chi sono questi stakeholder e creare separazioni (ad esempio classi separate) basate su tali stakeholder. Pertanto, potresti avere una classe UserCredential per la gestione delle password invece di inserirla in un'altra classe insieme ai dati che cambiano a causa delle motivazioni di altri stakeholder.

Il seguire SRP mantiene le cose semplici in molti degli stessi modi che ho menzionato in origine, ma semplifica anche le cose quando non si mischiano le modifiche apportate per motivi diversi nella stessa classe. Quindi, anche con questa revisione, SRP e KISS possono ancora vivere felici insieme.

    
risposta data 17.05.2013 - 17:58
fonte
6

Stai confondendo KISS; semplice non si riferisce al semplice attuare per lo sviluppatore, si riferisce al design semplice, semplice da capire e da usare. Seguire SRP rende il tuo codice più semplice da capire e da usare perché è più semplice usare una classe specifica per un singolo scopo rispetto a una classe multiuso, è anche più semplice da mantenere.

SRP supporta Simplicity, anche se è più lavoro da implementare per lo sviluppatore, il risultato è un sistema più semplice.

    
risposta data 17.05.2013 - 17:50
fonte