Esiste un antipattern per descrivere questo metodo di codifica? [chiuso]


26

Ho una base di codice in cui il programmatore tendeva a concludere le cose in aree che non avevano senso. Ad esempio, dato un registro degli errori, è possibile accedere tramite

ErrorLog.Log(ex, "friendly message");

Ha aggiunto vari altri mezzi per svolgere esattamente lo stesso compito. PER ESEMPIO

SomeClass.Log(ex, "friendly message");

Che semplicemente si gira e chiama il primo metodo. Ciò aggiunge livelli di complessità senza alcun vantaggio aggiunto. C'è un anti-pattern per descriverlo?


36
"Bad coding" lo copre;)
Oded,

12
Dipende. È un wrapper per una libreria di registrazione? Se mai ci fosse la possibilità che potesse essere scambiato, questa è in realtà una buona pratica ...
Rig

3
@lortabac: Il problema con il "codice baklava" è che suona davvero buono e gustoso, e quindi desiderabile.
FrustratedWithFormsDesigner

10
Cosa dice questo programmatore quando li aggiungi perché stanno aggiungendo questi metodi? Comprendere il loro ragionamento dovrebbe rendere più facile educarli.
Keith

3
Sembra un livello di riferimento indiretto , che può essere utile quando si desidera evitare l'accoppiamento tra due classi, come sottolineato da @Rig. Forse era solo un programmatore che soffriva di patternite - semplicemente provando qualche schema per risolvere un problema che non c'è, violando KISS.
Fuhrmanator,

Risposte:


54

Vale la pena chiamare Antipattern solo una cattiva abitudine di programmazione se è ragionevolmente diffusa.

Il resto lo chiamiamo semplicemente "codice spazzatura" ...


Se dovessi suggerire un nome per questa particolare cattiva abitudine, sarebbe "Disturbo dell'astrazione ossessiva" :-)


9
Ho sempre usato "Indirection Hell".
Dan Neely,

27

No, non è un modello anti ma vorrei sollevare i seguenti problemi.

Violazione della singola responsabilità Princple

SRP afferma che una classe dovrebbe avere un motivo per cambiare. L'aggiunta di un metodo logger significa che anche la classe deve cambiare se la logica di registrazione deve essere cambiata.

Violazione di una is-arelazione

Le classi di base non sono toolbox in cui è possibile aggiungere diversi metodi di praticità.

In questo modo si accoppiano in modo efficace tutte le classi ereditate alle implementazioni della classe base.

Confrontalo con la composizione.


1
"Problema di responsabilità singola"? SRP? Forse intendevi scrivere il principio di responsabilità singola? Sto solo collegando i due qui. :)
zxcdw,

8

Non che ciò lo renda accettabile, ma questo potrebbe essere solo un refactoring incompiuto. Forse SomeClass.log () aveva la sua logica e veniva implementato per primo. E in seguito si sono resi conto che avrebbero dovuto usare ErrorLog.Log (). Quindi, anziché modificare 100 posizioni in cui viene chiamato SomeClass.Log (), hanno appena delegato a ErrorLog.Log (). Personalmente cambierei tutti i riferimenti a ErrorLog.Log () o almeno commenterei SomeClass.log () per dire perché delega in questo modo.

Solo qualcosa da considerare.



4

Non sono sicuro di descriverlo come un'offesa al principio della singola responsabilità, perché se si verifica una modifica alla firma del metodo ErrorLog (il metodo chiamato da SomeClass), ogni codice client che chiama questo metodo fallirà.

Esiste ovviamente un modo per utilizzare l'ereditarietà (o creare classi che richiedono la registrazione implementando un'interfaccia di registrazione) lì.


Ancora cattiva pratica perché: 1) è improbabile che cambi 2) se cambia, possono semplicemente creare una classe wrapper con lo stesso nome e modificare le importazioni.
Kevin Cline,

2
+1. Ed ecco "Zio Bob" (Robert Martin) che sostiene a favore della centralizzazione delle dipendenze in un numero limitato di moduli, piuttosto che disperderle attraverso il codice.
MarkJ,

3

Oppure potremmo considerare questo come un "momento di insegnamento" :)

Il tuo sviluppatore potrebbe essere a metà strada per una buona idea. Supponiamo di voler avere il requisito che tutti i tuoi oggetti business siano in grado di registrare in modo intelligente. È possibile definire:

   public interface IBusinessObjectLogger
   {
       void Log(Exception ex, string logMessage)
   }

Ora interno ai tuoi oggetti puoi usare l'oggetto ErrorLog per eseguire effettivamente la registrazione mentre il codice SomeClass aggiunge un valore specifico dell'oggetto al messaggio di registro. È quindi possibile estendere ulteriormente le API di registrazione per implementare funzionalità di registrazione basata su file, db o messaggi, senza toccare gli oggetti business.


3

Non sono sicuro che questo sia automaticamente malvagio.

Se stai chiamando SomeClass.Log è sicuramente un male, ma se Log viene utilizzato solo da WITHIN SomeClass, sta tagliando l'accoppiamento e lo definirei accettabile.


2

Questo è in realtà abbastanza comune in alcuni stili di codifica e le basi della linea di pensiero non sono, di per sé, un anti-schema.

È molto probabilmente il risultato di qualcuno che codifica per necessità senza conoscere la base di codice più ampia: "OK, questo codice deve registrare un errore, ma quella funzione non è lo scopo principale del codice. Pertanto, ho bisogno di un metodo / classe che lo farà per me". Questo è un buon modo di pensare; ma, senza sapere che esiste ErrorLog, hanno creato SomeClass. Hanno poi trovato ErrorLog in un momento successivo, e invece di sostituire tutti gli usi del metodo che avevano inserito, hanno fatto chiamare il loro metodo ErrorLog. Ecco dove questo diventa un problema.


2

La complessità accidentale è la complessità che si presenta nei programmi per computer o nel loro processo di sviluppo che non è essenziale per il problema da risolvere. Mentre la complessità essenziale è inerente e inevitabile, la complessità accidentale è causata dall'approccio scelto per risolvere il problema.

http://en.wikipedia.org/wiki/Accidental_complexity


1

Potrebbe essere un abuso / incomprensione del modello di facciata . Ho visto cose simili in una base di codice con cui ho lavorato. Gli sviluppatori hanno attraversato una fase in cui erano pazzi per i modelli di progettazione senza comprendere i principi generali della progettazione OO.

Un uso improprio del modello di facciata provoca una sfocatura dei livelli di astrazione attraverso i livelli dell'applicazione.


1

Ciò che questo programmatore sta facendo è racchiudere un po 'di codice, in modo che non abbia una dipendenza diretta dal modulo di registrazione. Senza informazioni più specifiche, non è possibile fornire uno schema più specifico. (Che questi involucri non siano utili è la tua opinione che è impossibile concordare o non essere d'accordo senza molte più informazioni.)

I modelli che potrebbero rientrare sono Proxy , Delegate , Decorator , Composite o alcuni di questi che hanno a che fare con il wrapping, nascondere o distribuire le chiamate. Può una di queste cose in uno stato di sviluppo incompleto.


0

Potrei immaginare che sia una differenza culturale. Forse c'è una buona ragione per avere funzionalità duplicate in questa particolare base di codice. Potrei immaginare la facilità di scrittura per essere una tale ragione. Il programmatore di Python in me direbbe ancora che è male, dal momento che " Dovrebbe esserci uno - e preferibilmente solo un - modo invadente per farlo ", ma alcuni ragazzi del Perl potrebbero essere abituati al fatto che " Ce n'è più di uno modo di farlo ".


1
La facilità di scrittura iniziale non è una buona ragione per la duplicazione. Il codice errato potrebbe essere più semplice da scrivere la prima volta, ma ciò non semplifica la scrittura del codice nel lungo periodo. Cosa fa il nuovo arrivato con la funzionalità duplicata? Quale metodo chiama? Perde tempo a cercarli e a leggerli, solo per scoprire che fanno la stessa cosa.
Kazark,

Forse questo codice era originariamente inteso come un prototipo che poi è stato utilizzato (ab) come incremento. In tal caso, l'ottimizzazione per la scrittura iniziale sarebbe stata valida, credo.
Bengt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.