Sì, sarebbe fantastico in teoria ...
In effetti, la denominazione degli schemi di progettazione migliora la leggibilità. Questo è in realtà l'obiettivo degli schemi di progettazione in primo luogo. È molto più semplice dire:
I used an abstract factory, but maybe we should start switching to a builder for more flexibility.
al tuo collega quando spieghi la struttura del tuo codice, piuttosto che:
I made a parent class which is inherited by a few other classes, given that each of those classes have an intent to create complex objects; now, we should start creating those objects by calling different methods which will progressively extend each object, because it will allow us to customize the way we extend them depending on the circumstances.
La prima versione è chiara (a meno che la persona con cui parli non abbia idea di cosa sia una fabbrica o un costruttore). La seconda versione è difficile da capire ed è soggetta a interpretazione.
Anche l'applicazione delle convenzioni di denominazione per i modelli di progettazione è utile. Ciò consentirebbe ai principianti di essere abituati più rapidamente a tali modelli. L'apprendimento e l'applicazione di schemi di progettazione è difficile e l'aiuto di uno strumento di controllo statico migliorerebbe notevolmente la curva di apprendimento. Se hai provato ad implementare un wrapper, ma invece hai creato un adattatore, lo strumento di controllo statico ti mostrerà l'errore, con un punto bonus che ti dice che stai effettivamente utilizzando un adattatore.
... ma è difficile da fare in pratica
Quindi, puoi applicare le convenzioni di denominazione per i modelli di progettazione in pratica?
Non ne sono così sicuro. Ecco alcuni motivi:
-
Un modello di design è facile da capire per un essere umano, ma non per una macchina. Non è come una regola severa come "Dovresti sempre racchiudere gli oggetti che implementano IDisposable
in using
" : tale affermazione è facile da controllare per un'applicazione come l'analisi FxCop / Code. Un modello di design è ... beh, un modello. Non ha una struttura rigida; ci sono diversi modi per implementarlo, mentre anche le più piccole modifiche possono destabilizzare un controllore statico.
Ad esempio, prendi un modello di strategia. Al di fuori di un semplice esempio accademico, il controllore statico avrebbe difficoltà a sapere se il modello è usato o meno. Esempio:
/// <param name="combine">A function which takes two consecutive entries and combines
/// them into a single entry to print.</param>
public void GeneratePdf(
Consignee consignee,
IEnumerable<Entry> entries,
Func<Entry, Entry, ComplexEntry> combine)
{
}
Il comportamento può essere commutato in fase di esecuzione utilizzando una funzione diversa come argomento del parametro combine
. Questo non significa che questo è un modello di strategia. Forse per combinare diverse voci, dovrebbero essere utilizzate alcune tecniche avanzate, quelle tecniche che sono contenute nella libreria del chiamante, quindi è impossibile utilizzarle da quella chiamata, a causa delle dipendenze circolari.
-
Allo stesso modo, le definizioni non sono abbastanza severe.
La regola IDisposable
sopra è estremamente severa. Hai un oggetto con un'interfaccia specifica? O lo metti dentro un using
, e la regola sarà soddisfatta, oppure no. La maggior parte delle regole (così come quella con IDisposable
) hanno eccezioni, ma quelle eccezioni sono anche estremamente rigide e precise.
I modelli di progettazione, d'altra parte, hanno definizioni, ma queste definizioni possono essere piegate per adattarsi a situazioni diverse. Ad esempio, un campo static readonly
sarebbe un singleton? Che dire di una proprietà con un campo di appoggio e una serratura? Queste due situazioni sono radicalmente diverse e, tuttavia, possono rappresentare un singleton.
Immagina quanto sarebbe difficile verificare se qualcosa è un adattatore o un'interfaccia fluente. Ad esempio, qualsiasi metodo di una classe che restituisce un'istanza della classe stessa è considerato un'interfaccia fluente?
-
Il controllo statico è usato principalmente dagli sviluppatori che conoscono il loro lavoro. Per lo più non hanno bisogno di uno strumento che indichi che stanno usando la parola chiave Strategy
, ma non utilizzano un modello di strategia. O stanno effettivamente usando un modello di strategia, e il controllo statico è sbagliato, o stanno consigliando consapevolmente la classe / metodo in questo modo, senza alcun intento di usare un modello di strategia reale.
I principianti, cioè le persone che possono trarre beneficio da un controllore statico, non lo userebbero, perché non sanno usare pedine statiche, e anche se lo sanno, vedono tali strumenti più come un disturbo, un cosa fastidiosa che li infastidisce con un sacco di avvertimenti difficili da capire.
Per concludere, applicare le convenzioni di denominazione per i modelli di progettazione è un compito difficile e molto probabilmente fornirebbe molti falsi positivi e falsi negativi. Non sarà molto utile, ma potrebbe essere molto fastidioso.
A proposito, c'è una sorta di checker statici molto intelligenti: i tuoi pari. Se qualcuno abusa di uno schema di progettazione, verrà evidenziato durante una revisione del codice. I checker statici sono eccellenti per eseguire operazioni ripetitive di base, come controllare la conformità del codice a regole severe. Tieni questo controllo di base per loro, mentre le scelte che richiedono di pensare e prendere decisioni rimarranno un compito degli sviluppatori che controllano il codice durante una revisione del codice.