La tua domanda sembra aver ereditato un grande sistema legacy di cui occuparti e stai cercando un modello di design magico che lo renda semplice.
È tutto a causa dell'ereditarietà?
Siamo onesti: qualsiasi sistema di maggiori dimensioni sembra complesso e difficile da capire a prima vista. Questo a causa delle questioni complesse con cui hanno a che fare.
Il sistema deve essere scomposto in parti più piccole e comprensibili. Ma quale sarebbe l'alternativa all'eredità nel tuo caso? Sub-routine di calcolo piatto che scrivono tutto ancora e ancora con un sacco di parametri per indicare le variabili e la variante di calcolo da utilizzare?
Questo non produrrebbe un codice ancora più difficile in cui non sei mai sicuro che se cambi qualcosa in una formula non dovresti adattare altre formule altrove? Non vorresti poi postare una domanda come ho ereditato 200K righe di codice spaghetti - e ora? .
Tuttavia, il codice è scritto, più classi hai, più difficile sarà capire. È naturale.
Alcuni psicologi sostengono addirittura che il nostro cervello ha in media una capacità di memoria a breve termine di circa 7 item, e cercare di capire l'interrelazione simultanea tra più item sembra difficile. Secondo loro, l'unico modo per superare questa limitazione sarebbero gli elementi del cluster. E l'ereditarietà è proprio così: puoi gestire l'oggetto derivato come l'oggetto originale, con solo le variazioni di cui avresti bisogno. Quindi dovrebbe essere più semplice da capire.
Ciò che è difficile da padroneggiare è il modo in cui tutte le classi sono correlate. Non solo nella loro struttura statica, ma anche in che modo interagiscono dinamicamente in fase di esecuzione.
Come è progettato il tuo sistema?
La lettura del codice può darti una visione dettagliata, classe per classe. Con un buon IDE, non dovrebbe esserci un problema per navigare tra classi correlate e trovare tutti i pezzi di codice relativi.
Ma questo non è sufficiente per ottenere la prospettiva e la comprensione generale del sistema:
The worst possible documentation to create for an object-oriented
system is a stand-alone description of the semantics of each method on
a class-by-class basis. This approach tends to generate a great deal
of useless documentation that no one reads or trusts, and fails to
document the more important architectural issues that transcend
individual classes, namely, the collaborations among classes and
objects.
- Grady Booch in Object-Oriented Analysis and Design
Ad esempio, è una pratica comune definire relazioni di alto livello tra classi astratte, per ridurre le dipendenze nelle classi concrete derivate. Ma questo rende facile perdere di vista queste relazioni quando si implementano le lezioni concrete. Ed a volte è difficile indovinare l'intento dietro l'astrazione.
Soluzione
Sfortunatamente, non esiste un modello di progettazione per scopi generali per superare la complessità. Non esiste una soluzione: per prima cosa devi comprendere a fondo il tuo sistema:
- Se esiste un documento di progettazione architettonica, iniziare da quello.
- In caso contrario, effettuare un reverse engineering. Inizia con un diagramma di classe. Esistono strumenti automatici che possono aiutarti.
- Quindi, se hai familiarità con i modelli di progettazione, prova a identificare nella struttura alcuni schemi di progettazione esistenti. Questo accelererà la tua comprensione della relazione dinamica tra le classi.
Forse con una comprensione più profonda scoprirai che il codice è strutturato meglio di quanto pensavi. E forse no. E in questo caso puoi tornare con ulteriori domande specifiche, per le quali possiamo fornire alcune idee su specifici modelli di progettazione per il miglioramento.