Che cos'è un anti-pattern?


194

Sto studiando schemi e anti-schemi. Ho un'idea chiara degli schemi, ma non ottengo gli anti-schemi. Le definizioni dal web e da Wikipedia mi confondono molto.

Qualcuno può spiegarmi in parole semplici cos'è un anti-pattern? Qual è lo scopo? Cosa fanno? È una cosa cattiva o buona?




È considerato cattivo, ma potrebbe essere l'unica soluzione. Pensaci due volte e vai.
Константин Ван

Risposte:


245

Gli anti-pattern sono alcuni schemi nello sviluppo del software che sono considerati cattive pratiche di programmazione.

A differenza dei modelli di progettazione che sono approcci comuni ai problemi comuni che sono stati formalizzati e generalmente considerati una buona pratica di sviluppo, gli anti-schemi sono l'opposto e sono indesiderabili.

Ad esempio, nella programmazione orientata agli oggetti, l'idea è di separare il software in piccoli pezzi chiamati oggetti. Un anti-pattern nella programmazione orientata agli oggetti è un oggetto God che svolge molte funzioni che sarebbero meglio separate in oggetti diversi.

Per esempio:

class GodObject {
    function PerformInitialization() {}
    function ReadFromFile() {}
    function WriteToFile() {}
    function DisplayToScreen() {}
    function PerformCalculation() {}
    function ValidateInput() {}
    // and so on... //
}

L'esempio sopra ha un oggetto che fa tutto . Nella programmazione orientata agli oggetti, sarebbe preferibile avere responsabilità ben definite per oggetti diversi per mantenere il codice meno accoppiato e in definitiva più gestibile:

class FileInputOutput {
    function ReadFromFile() {}
    function WriteToFile() {}
}

class UserInputOutput {
    function DisplayToScreen() {}
    function ValidateInput() {}
}

class Logic {
    function PerformInitialization() {}
    function PerformCalculation() {}
}

La linea di fondo è che ci sono buoni modi per sviluppare software con modelli comunemente usati (modelli di progettazione ), ma ci sono anche modi in cui il software viene sviluppato e implementato che può portare a problemi. I pattern considerati cattive pratiche di sviluppo software sono anti-pattern.


9
qualche altro esempio di Anti-Patterns accanto a GodObject?
Tomasz Mularczyk,

@Tomasz Programming Pasta serve è uno di questi esempi. È meglio generalizzato come scarso incapsulamento tra molti piccoli oggetti. Consideralo l'opposto dell'oggetto Dio en.wikipedia.org/wiki/Spaghetti_code
AWrightIV

@Tomasz tutto ciò che è male, ma è fatto da alcune persone, è un antipasto. Ad esempio, try: <do something>; except: passpotrebbe essere il cardinale Sin antipattern in Python. Vedi questo: realpython.com/blog/python/…
eric

1
Un Singleton può essere considerato un anti-pattern perché rende più difficile deridere ed eseguire test in parallelo (poiché tutti i test usano e mutano lo stesso singleton, causando incoerenze)?
lostsoul29,

63

Ogni volta che sento parlare di Anti-pattern, ricordo un altro termine, vale a dire. Odore di design.

"Gli odori del design sono determinate strutture nel design che indicano la violazione dei principi fondamentali del design e influiscono negativamente sulla qualità del design".

Esistono molti odori di design classificati in base a principi di progettazione violanti:

Odori di astrazione

Astrazione mancante: questo odore si presenta quando vengono utilizzati gruppi di dati o stringhe codificate anziché creare una classe o un'interfaccia.

Astrazione imperativa: questo odore si presenta quando un'operazione viene trasformata in una classe.

Astrazione incompleta: questo odore si presenta quando un'astrazione non supporta completamente metodi complementari o correlati.

Astrazione sfaccettata: questo odore si presenta quando un'astrazione ha più di una responsabilità assegnata ad essa.

Astrazione non necessaria: questo odore si verifica quando un'astrazione che in realtà non è necessaria (e quindi avrebbe potuto essere evitata) viene introdotta in una progettazione software.

Astrazione non utilizzata: questo odore si presenta quando un'astrazione viene lasciata inutilizzata (non utilizzata direttamente o non raggiungibile).

Astrazione duplicata: questo odore si presenta quando due o più astrazioni hanno nomi identici o implementazione identica o entrambi.

Odori di incapsulamento

Incapsulamento carente: questo odore si verifica quando l'accessibilità dichiarata di uno o più membri di un'astrazione è più permissiva di quanto effettivamente richiesto.

Incapsulamento che perde : questo odore si presenta quando un'astrazione "espone" o "perde" i dettagli dell'implementazione attraverso la sua interfaccia pubblica.

Incapsulamento mancante: questo odore si verifica quando le variazioni di implementazione non sono incapsulate all'interno di un'astrazione o gerarchia.

Incapsulamento non sfruttato: questo odore si presenta quando il codice client utilizza controlli di tipo espliciti (usando istruzioni incatenate if-else o switch che controllano il tipo di oggetto) invece di sfruttare la variazione dei tipi già incapsulati all'interno di una gerarchia.

Odori di modularizzazione

Modularizzazione interrotta: questo odore si presenta quando i dati e / o i metodi che idealmente avrebbero dovuto essere localizzati in una singola astrazione vengono separati e diffusi tra più astrazioni.

Modularizzazione insufficiente: questo odore si presenta quando esiste un'astrazione che non è stata completamente decomposta e un'ulteriore decomposizione potrebbe ridurne le dimensioni, la complessità di implementazione o entrambi.

Modularizzazione ciclicamente dipendente: questo odore nasce quando due o più astrazioni dipendono l'una dall'altra direttamente o indirettamente (creando un accoppiamento stretto tra le astrazioni).

Modularizzazione simile ad un hub: questo odore si presenta quando un'astrazione ha dipendenze (sia in entrata che in uscita) con un gran numero di altre astrazioni.

Gli odori della gerarchia

Gerarchia mancante: questo odore si presenta quando un segmento di codice utilizza la logica condizionale (in genere in combinazione con "tipi con tag") per gestire esplicitamente la variazione nel comportamento in cui una gerarchia avrebbe potuto essere creata e utilizzata per incapsulare tali variazioni.

Gerarchia non necessaria: questo odore nasce quando l'intera gerarchia ereditaria non è necessaria, indicando che l'ereditarietà è stata applicata inutilmente per il particolare contesto di progettazione.

Gerarchia non fattorizzata: questo odore si presenta quando c'è una duplicazione non necessaria tra i tipi in una gerarchia.

Gerarchia ampia: questo odore si presenta quando una gerarchia ereditaria è "troppo" ampia indicando che potrebbero mancare tipi intermedi.

Gerarchia speculativa: questo odore si presenta quando uno o più tipi in una gerarchia sono forniti in modo speculativo (cioè, sulla base di bisogni immaginati piuttosto che di requisiti reali).

Gerarchia profonda: questo odore nasce quando una gerarchia ereditaria è "eccessivamente" profonda.

Gerarchia ribelle: questo odore si presenta quando un sottotipo rifiuta i metodi forniti dai suoi supertipi.

Gerarchia spezzata: questo odore si presenta quando un supertipo e il suo sottotipo concettualmente non condividono una relazione "IS-A" con conseguente sostituibilità interrotta.

Gerarchia multipath: questo odore nasce quando un sottotipo eredita sia direttamente che indirettamente da un supertipo che porta a percorsi di eredità non necessari nella gerarchia.

Gerarchia ciclica: questo odore si presenta quando un supertipo in una gerarchia dipende da uno qualsiasi dei suoi sottotipi.


La definizione e la classificazione di cui sopra sono descritte in "Refactoring per gli odori di progettazione software: gestione del debito tecnico ". Alcune risorse più rilevanti possono essere trovate qui .


41

Un modello è un'idea di come risolvere un problema di qualche classe. Un anti-pattern è un'idea di come non risolverlo perché implementare quell'idea si tradurrebbe in un cattivo design.

Un esempio: un "modello" sarebbe usare una funzione per riutilizzare il codice, un "modello" sarebbe usare copia-incolla per lo stesso. Entrambi risolvono lo stesso problema, ma l'utilizzo di una funzione di solito porta a un codice più leggibile e gestibile rispetto al copia-incolla.


18

Un anti-pattern è un modo per non risolvere un problema. Ma c'è di più: è anche un modo che può essere visto frequentemente nei tentativi di risolvere il problema.


13

Se desideri davvero studiare AntiPatterns, procurati il ​​libro AntiPatterns (ISBN-13: 978-0471197133).

In esso, definiscono "Un AntiPattern è una forma letteraria che descrive una soluzione comune a un problema che genera conseguenze decisamente negative."

Pertanto, se si tratta di una cattiva pratica di programmazione, ma non di una pratica comune, limitata a un'applicazione, a una società o a un programmatore, non soddisfa la parte "Pattern" della definizione di AntiPattern.


9

Un modo comune per fare casino. Come la classe god / kitchensink (fa tutto), per esempio.


6

È interessante notare che un determinato modo di risolvere un problema può essere sia un modello che un anti-modello. Singleton ne è il primo esempio. Apparirà in entrambi i set di letteratura.


6

Un anti-pattern è il complemento di un design pattern . Un anti-pattern è una soluzione template che non dovresti usare in una determinata situazione.


6

Proprio come con un modello di progettazione , un modello anti-modello è anche un modello e un modo ripetibile di risolvere un determinato problema, ma in modo non ottimale e inefficace.


4

Oggi, i ricercatori e i professionisti dell'ingegneria del software usano spesso i termini "anti-pattern" e "odore" in modo intercambiabile. Tuttavia, concettualmente non sono la stessa cosa. La voce Wikipedia di anti-pattern afferma che un anti-pattern è diverso da una cattiva pratica o da una cattiva idea di almeno due fattori. Un anti-pattern è

"Un processo, una struttura o un modello di azione comunemente usati che, nonostante appaia inizialmente come una risposta appropriata ed efficace a un problema, in genere ha più conseguenze negative che risultati positivi."

Indica chiaramente che un antimodello viene scelto nella convinzione che sia una buona soluzione (come un modello) al problema presentato; tuttavia, porta più responsabilità che benefici. D'altra parte, un odore è semplicemente una cattiva pratica che influisce negativamente sulla qualità di un sistema software. Ad esempio, Singleton è un anti-pattern e la classe God (o Insufficient Modularization) è un odore di design.


2

Gli anti-schemi sono modi comuni in cui le persone tendono a programmare nel modo sbagliato, o almeno nel modo non buono.


0

Qualsiasi modello di progettazione che sta causando più danni che benefici all'ambiente di sviluppo software dato sarebbe considerato anti-modello.

Alcuni anti-pattern sono evidenti, ma altri no. Ad esempio Singleton, anche se molti lo considerano un buon vecchio modello di design ma ci sono altri che non lo fanno.

Puoi controllare la domanda Cosa c'è di male nei single? per comprendere meglio le diverse opinioni al riguardo.


In realtà, gli anti-pattern generalmente non sono evidenti. Ovviamente i cattivi schemi di progettazione sono semplicemente cattivi schemi di progettazione. Un vero anti-pattern sembra sostenibile sulla superficie, ma in seguito manifesta problemi. In realtà, non essere ovviamente cattivo è la distinzione che li rende in primo luogo un anti-schema.
hawkeyegold,

0

Come in Algorithm puoi ottenere la soluzione usando la forza bruta, ma devi pagare molto se la situazione diventa complessa.

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.