SOC, Separation of concerns

_Logo Il Separation of concerns è uno dei più importanti principi di progettazione software e il concetto alla base è abbastanza semplice e spesso lo si applica senza nominarlo: suddividere l'applicazione in elementi distinti, ognuno rivolto ad uno specifico concern, quindi ad una specifica competenza.

Il principio in se è pertanto semplice ma tante sono le strade percorribili per soddisfarlo. E’ un concetto che è ripetuto in ogni contesto e fondamentalmente significa che organizzare semplifica l’attività che si sta svolgendo. Banalmente, se organizzo una dispensa in modo che i prodotti siano organizzati per tipologia, mi sarà più semplice trovare quello che cerco, non dovrò incasinare un intero scaffale per trovare un certo prodotto e sarà più semplice ottimizzare lo spazio.

Nel design di un applicativo si tende quindi a non mescolare tra loro differenti funzionalità e aspetti, garantendo che tra i vari elementi dell’applicativo, piccoli e grandi che siano, non vi siano un legame troppo stretto (si parla di tightly coupled). Questo porta a progettare software modulari, in cui un modulo può essere a sua volta composto da altri moduli più piccoli.

L’articolo disponibile su DevIQ propone l’esempio del recupero di informazioni secondo certi criteri e la loro formattazione al fine di presentarle all’utente. Se questi due aspetti vengono eseguiti dallo stesso elemento avremo una violazione del SOC: non potremmo ad esempio presentare quegli stessi dati in modo diverso, senza metter mano a quell’elemento che però è già utilizzato altrove. In questi casi si tende ad utilizzare due elementi distinti: uno per il recupero e l’altro per la presentazione. Questo permette di cambiare uno e l’altro e di combinare diverse logiche di recupero con diverse logiche di presentazione, senza modificare quelle esistenti.

Un altro vantaggio, spesso sottovalutato, riguarda la riduzione della complessità del sistema, perché possono guardare la suddivisione in moduli ad alto livello o scendere al dettaglio che desidero. La comprensibilità è uno degli obbiettivi di tale principio, assieme naturalmente alla manutenibilità, estendibilità e testabilità:

  • La modifica legata ad una funzionalità non comporta la modifica di più moduli.
  • E' più facile riutilizzare i moduli e combinarli tra loro.
  • Il test dei moduli risulta semplificato.
  • E' più facile sostituire i moduli con altri che ne soddisfano la competenza.

E' importante che tali competenze siano il più possibile indipendenti: il grado di indipendenza tra oggetti è un altro importante parametro nella definizione di un sistema e viene chiamato coupling. Quando si ha un basso livello di coupling si ottiene un alto livello di cohesion, che misura il grado di legame degli elementi di un modulo con il concern del modulo stesso. Avremo ad esempio che i membri di una classe saranno legati alla competenza della classe, mentre le classi del progetto dedicato al Data Access saranno tutte legate alla persistenza dei dati.

E' ovvio che non tutti i moduli di un sistema possono essere indipendenti: notification, logging, data access, memory managment, data validation, caching e molti altri moduli sono riutilizzati in modo trasversale. Garantire la correttezza di tali moduli evita che eventuali errori vengano distribuiti su tanti altri moduli. Si parla in questo caso di Cross-cutting concern.

Legato a questo principio progettuale vi è anche il Principio di singola responsabilità, in cui ogni elemento dell'applicazione deve avere una sola responsabilità. In pratica lo stesso principio ma più vincolante.

Sempre l‘articolo di DevIQ mette in evidenza un altro importante principio detto Don’t Repeat Yourself, sostenendo che il primo è conseguenza del secondo. Dover evitare di ripetere le stesse competenze in più parti dell’applicazione, utilizzando astrazione e incapsulamento, porta di fatto ad organizzare gli elementi del progetto, adempiendo al Separation of concerns.

Tag: SOC, OOP, design, principi