Tieni presente la metrica di stabilità di Martin e cosa intende per "stabilità":
Instability = Ce / (Ca+Ce)
O:
Instability = Outgoing / (Incoming+Outgoing)
Cioè, un pacchetto è considerato completamente instabile se tutte le sue dipendenze sono in uscita: usa altre cose, ma nulla lo usa. In quel caso, ha senso solo che quella cosa sia concreta. Sarà anche il tipo di codice più semplice da modificare poiché nient'altro lo utilizza e quindi nient'altro può rompersi se quel codice viene modificato.
Nel frattempo, quando hai lo scenario opposto di completa "stabilità" con un pacchetto usato da una o più cose ma non usa nulla da solo, come un pacchetto centrale usato dal software, è quando Martin dice che dovrebbe essere astratto. Ciò è anche rafforzato dalla parte DIP di SOLI (D), il principio di inversione di dipendenza, che afferma sostanzialmente che le dipendenze dovrebbero fluire uniformemente verso le astrazioni sia per il codice basso che per quello di alto livello.
Cioè, le dipendenze dovrebbero fluire uniformemente verso la "stabilità" e, più precisamente, le dipendenze dovrebbero fluire verso pacchetti con più dipendenze in entrata rispetto alle dipendenze in uscita e, inoltre, le dipendenze dovrebbero fluire verso le astrazioni. L'essenza della logica alla base di ciò è che le astrazioni forniscono spazio per sostituire un sottotipo con un altro, offrendo quel grado di flessibilità per le parti in calcestruzzo che implementano l'interfaccia per cambiare senza spezzare le dipendenze in entrata in quella interfaccia astratta.
Ci sono degli svantaggi significativi a seconda delle astrazioni?
Bene, in realtà non sono d'accordo con Martin qui per il mio dominio, e qui ho bisogno di introdurre una nuova definizione di "stabilità" come in "mancanza di ragioni per cambiare". In quel caso direi che le dipendenze dovrebbero fluire verso la stabilità, ma le interfacce astratte non aiutano se le interfacce astratte sono instabili (secondo la mia definizione di "instabile", come soggetto a ripetute modifiche, non a quelle di Martin). Se gli sviluppatori non riescono a ottenere le astrazioni corrette e i clienti cambiano ripetutamente idea in modo da rendere astratti i tentativi di modellare il software incompleto o inefficace, allora non beneficiamo più della maggiore flessibilità delle interfacce astratte per proteggere il sistema da cambiamenti a cascata che dipendono dalla dipendenza . Nel mio caso personale ho trovato motori ECS, come quelli trovati nei giochi AAA,più concreti : verso i dati grezzi, ma tali dati sono altamente stabili (come in ", è improbabile che debbano mai essere cambiati"). Ho trovato spesso la probabilità che qualcosa che richieda cambiamenti futuri sia una metrica più utile del rapporto tra accoppiamenti efferenti e totali nel guidare le decisioni SE.
Quindi altererei un po 'il DIP e direi semplicemente che "le dipendenze dovrebbero fluire verso componenti che hanno la più bassa probabilità di richiedere ulteriori modifiche", indipendentemente dal fatto che tali componenti siano interfacce astratte o dati grezzi. Tutto ciò che conta per me è la probabilità che possano richiedere modifiche dirette alla progettazione. Le astrazioni sono utili in questo contesto di stabilità solo se qualcosa, essendo astratto, riduce tale probabilità.
Per molti contesti questo potrebbe essere il caso di ingegneri e clienti decenti che anticipano le esigenze del software in anticipo e progettano astrazioni stabili (come in, immutabili), mentre quelle astrazioni offrono loro tutto il respiro di cui hanno bisogno per scambiare implementazioni concrete. Ma in alcuni domini, le astrazioni potrebbero essere instabili e inclini a essere inadeguate, mentre i dati richiesti dal motore potrebbero essere molto più facili da anticipare e rendere stabili in anticipo. Quindi, in quei casi, può effettivamente essere più vantaggioso dal punto di vista della manutenibilità (la facilità di cambiare ed estendere il sistema) affinché le dipendenze fluiscano verso i dati piuttosto che verso le astrazioni. In un ECS, le parti più instabili (come nelle parti più frequentemente modificate) sono in genere le funzionalità che risiedono nei sistemi (PhysicsSystem
, ad esempio), mentre le parti più stabili (come nella probabilità meno probabile che vengano modificate) sono i componenti costituiti solo da dati non MotionComponent
elaborati ( ad esempio) utilizzati da tutti i sistemi.