Non userei il termine ambiguo, ma senza dubbio c'è un elemento significativo del giudizio situazionale .
Per rispondere alla tua domanda in anticipo, no, non esiste un mezzo di verifica formale e matematicamente verificabile per verificarne la conformità.
Il motivo è perché non tutti i programmi software e domini sono uguali. Joel ha toccato questo argomento nel suo saggio Five Worlds . Un enorme software di gestione dei processi aziendali richiede approcci progettuali diversi rispetto al software che controlla un distributore automatico.
Riconoscerò che l'SRP è uno dei concetti più pesanti per il giudizio del gruppo SOLID e ci sono tonnellate di cattive descrizioni là fuori. Spesso volte, scritto dagli autori solidamente nell'e.g. mondo di consultingware aziendale, scrivendo affermazioni assolute completamente inconsapevoli o ignorando aspetti di altri mondi. La "ragione per cui cambiare" le persone che scrivono spesso le trovo particolarmente insensate e vaghe. Penso che i principi SOLID siano più adatti ai tipi di software di consulenza aziendale e agli autori professionisti, ad es. Lo zio Bob si guadagna da vivere vendendo i loro servizi a quei tipi di società. Quindi, a meno che tu non sia anche tu in quel mondo, devi riconoscere ciò che è appropriato per la tua situazione.
Una singola responsabilità può significare cose diverse per persone diverse in situazioni diverse. Ad esempio, di recente ho avuto bisogno di un corso per gestire le impostazioni di un programma. Quella classe legge il file di configurazione, lo analizza, ha i mezzi per accedere ai valori di configurazione e può riportare la configurazione sul disco. Tutto ciò, in una singola classe, ConfigurationSettings
. Nella mia particolare circostanza, nonostante abbia fatto molte cose diverse e disparate, direi che la mia classe si attiene a una singola responsabilità: occuparsi della configurazione.
Ora, alcune persone direbbero che il mio design è difettoso, fa troppo. Dovrei iniettare in un oggetto parser di file config, avere un factory IConfig astratto che istanzia la classe ConfigSettings invece di new()
, o un mucchio di altre cose per rompere ulteriormente le responsabilità di quella classe.
Chi ha ragione? Dipende da come la singola responsabilità si inserisce nel quadro più ampio. Ho visto alcuni autori fare affidamento su "ad un dato livello di astrazione" sulla descrizione della singola responsabilità, che a mio avviso ha molto senso. E così nella mia situazione, al mio livello di astrazione scelto, la mia classe ConfigurationSettings
fa una sola cosa, persiste le impostazioni del mio programma. I dettagli di quel formato di file di configurazione, dove sono salvati, ecc. Sono cose che non hanno importanza nel quadro generale, e a nessuno importa dove vanno.
Che tipo di situazione ci sarebbe dove gli amanti astratti della fabbrica avrebbero ragione sulla mia classe? Spesso, sarebbero persone in quel mondo mega-impresa. Il mio software ha esattamente 1 cliente e non avrà mai più di quel singolo cliente. Posso avere un processo di aggiornamento che consiste esclusivamente di "eliminare la vecchia versione, installare quella nuova". Se introduco una modifica alle impostazioni di configurazione che non è retrocompatibile con i vecchi formati, posso semplicemente farli eliminare la vecchia configurazione e ricominciare da capo.
Non tutti possono essere così disinvolti riguardo alle loro impostazioni di configurazione. Alcune persone potrebbero scrivere software per centinaia o migliaia di clienti. Potrebbe dover gestire e preservare diversi formati tra diverse versioni del loro software. Potrebbero dover supportare una singola configurazione condivisa da più computer, tutti leggendo dallo stesso posto. Non devo fare nulla di tutto ciò. Ma per queste altre persone, il formato del file, la posizione, ecc. importa. In quelle situazioni, l'iniezione di un parser nella mia classe di configurazione potrebbe avere senso una volta capito il formato in cui si trovano le impostazioni. Potrebbe avere senso avere una fabbrica che lo capisca. Potrebbe avere senso avere un sistema di notifica per quando le impostazioni vengono modificate, invece di un insieme di variabili statiche (globali) come sto usando.
E se stavo scrivendo software per migliaia di cliniche dentistiche per pianificare appuntamenti e fare fatturazione, la mia classe di configurazione sarebbe senza dubbio non appropriata. Ma non è quello che sto facendo, così è.
A corto di intelligenza artificiale di livello skynet, nessuno strumento di analisi statica sarà in grado di esaminare una classe e capire quale sia il suo livello di astrazione previsto, e quindi non può effettuare alcuna determinazione significativa della conformità SRP o meno.