it-swarm.it

Quali modelli di design sono i peggiori o più definiti in modo restrittivo?

Per ogni progetto di programmazione, i manager con precedenti esperienze di programmazione cercano di brillare quando raccomandano alcuni schemi di progettazione per il tuo progetto. Mi piacciono i modelli di design quando hanno senso o se hai bisogno di una soluzione scalabile. Ho usato Proxy, osservatori e modelli di comando in modo positivo, ad esempio, e lo faccio ogni giorno. Ma sono davvero titubante nel dire un modello Factory se esiste un solo modo per creare un oggetto, poiché una factory potrebbe rendere tutto più semplice in futuro, ma complica il codice ed è un vero e proprio overhead.

Quindi, la mia domanda è relativa alla mia carriera futura e la mia risposta ai tipi di manager che gettano nomi di pattern casuali in giro:

Quali modelli di design hai usato, che ti hanno respinto nel complesso? Quali sono i peggiori schemi di progettazione, quelli che dovresti considerare tranne che in un'unica situazione in cui hanno senso (leggi: quali schemi di progettazione sono definiti in modo molto stretto)? (È come se stessi cercando le recensioni negative di un buon prodotto complessivo di Amazon per vedere cosa infastidiva maggiormente le persone nell'usare i modelli di design.) E non sto parlando di Anti-Patterns qui, ma di Pattern che di solito sono pensati come modelli "buoni".

Modifica: Come alcuni hanno risposto, il problema è spesso che i modelli non sono "cattivi" ma "usati male". Se conosci schemi, che sono spesso usati in modo improprio o addirittura difficili da usare, si adatterebbero anche come risposta.

28
Akku

Non credo nei modelli cattivi, credo che i modelli possano essere applicati male!

  • IMHO il singleton è il modello più abusato e applicato erroneamente. Le persone sembrano avere una malattia singleton e iniziare a vedere le possibilità per i single dappertutto senza considerare alternative.
  • IMHO modello visitatore ha l'uso più limitato e quasi mai la complessità aggiunta sarà giustificata. È possibile ottenere un pdf di Nizza qui . In realtà solo quando si dispone di una struttura di dati che si sa che verrà attraversata mentre si eseguono diverse operazioni sulla struttura di dati senza conoscere tutti i modi in anticipo, dare al visitatore una possibilità di combattimento. È carino però :)

Per questa risposta ho considerato solo i modelli GOF. Non conosco tutti i possibili schemi abbastanza bene da tenerne conto anche.

40
KeesDijk

Ho intenzione di uscire su un arto qui e suggerire un uso eccessivo dell'eredità. Decisamente più applicabile in lingue senza un solido supporto del polimorfismo in fase di compilazione, come Java. L'eredità di runtime è uno strumento, non una sorta di meraviglia per tutte le funzionalità.

Altre persone hanno già espresso qualcosa di simile al mio odio personale per i Singleton, quindi non ho intenzione di approfondire qui.

14
DeadMG

A parte Singleton e Visitor già citati dagli altri risponditori, non conosco modelli di design "famigerati". I problemi maggiori di IMHO non derivano dal fatto che uno specifico modello di progettazione sia "sbagliato", ma piuttosto dagli sviluppatori che applicano i modelli troppo avidamente.

Quasi tutti attraversano la fase della "febbre dei modelli" quando conoscono i modelli. Pensando che i modelli siano la cosa migliore dopo il pane a fette, inizialmente si cerca di applicarli ogni volta che vede una possibilità. Ciò comporta che il codice venga sepolto sotto schemi, in cui gli schemi stessi non aiutano più, rendono il codice più difficile da comprendere e mantenere a lungo termine.

Alla fine, la maggior parte di noi supera questa fase e inizia a imparare a usare gli schemi per risolvere problemi reali, non per se stessi. I modelli hanno il loro prezzo, che è una complessità aggiunta, e l'applicazione di qualsiasi modello specifico è giustificata solo quando ripaga per la complessità aggiunta, contribuendo a semplificare qualche altra parte del sistema, rendendo così il codice/la configurazione nel complesso più facili da capire e mantenere. In caso contrario, è spesso meglio stare lontano dai modelli, attenendosi alla soluzione più semplice che potrebbe funzionare.

14
Péter Török

Singleton. È sui modelli GOF che ora è più spesso chiamato anti-pattern. Uno dei motivi è che Singleton rende il codice più difficile da testare.

10
SiberianGuy

Se conosci schemi, che sono spesso usati in modo improprio o addirittura difficili da usare, si adatterebbero anche come risposta.

Seguendo modello MVVM per [~ # ~] wpf [~ # ~] troppo rigorosamente, come indicato ad esempio - con questa domanda . Alcune persone cercano di seguire le linee guida secondo cui nessun codice dovrebbe essere inserito troppo strettamente nel codice e escogitare tutti i tipi di hack esotici.

E naturalmente, MVVM è difficile da morire, e non ne vale la pena per piccoli progetti a breve termine.

Il Dr. WPF ha pubblicato un post ironico al riguardo nel suo articolo M-V-poo .

7
Steven Jeuris

Factory. Ho visto il codice implementarlo che crea un solo tipo. Questo è completamente inutile codice IMO. Non aiuta il fatto che molti degli esempi online siano completamente inventati. Fabbrica di pizza?

Forse la fabbrica è più facile da testare a causa dell'iniezione di dipendenza. Ma aggiungere quel codice quando non ne avrai bisogno non ha senso per me, e l'argomento test scompare quando puoi usare framework finti come JMockit. Più è semplice creare un programma, meglio è. Le fabbriche hanno davvero senso solo con un numero maggiore di tipi (per maggiore, intendo almeno più di 2).

5
Michael K

Alcuni dei modelli nel libro GOF sono specifici del C++, nel senso che sono meno applicabili nei linguaggi con la riflessione, ad es. il modello prototipo è meno significativo in Java.

Considero il modello dell'interprete come "stretto". Devi avere un problema generale che vale la pena sviluppare un risolutore di problemi generali. Funziona solo per problemi speciali per i quali è possibile inventare una lingua, definire una grammatica e scrivere un interprete. Le istanze del problema dovrebbero essere rappresentabili come una frase nella grammatica. Non penso che ti imbatti spesso in queste situazioni.

5
Karl

Quello di cui mi pento più spesso (anche se non con maggiore veemenza): quando avrei dovuto creare una funzione ma ho implementato una soluzione OOP.

5
C SD

Singleton

Concordo con gli altri su Singleton. Non che non dovresti mai usarli, solo che dovrebbe essere limitato a pochissimi casi. Sono usati come globuli pigri per la maggior parte del tempo.

La sicurezza del thread è un problema con i singoli. La gestione delle eccezioni è un altro - se il singleton non riesce a creare correttamente - non si sa sempre se è possibile rilevare l'errore in modo sicuro, in particolare se si tratta di uno di quegli oggetti creati "prima di main". E poi c'è il problema di ripulire dopo.

Tendo a preferire l'uso di un singleton e fare in modo che tutti gli altri singoli "aspiranti" si "iscrivano" al tuo. Il mio uso singleton più comune è la gestione di "shout event": hai solo "trasmesso al mondo" che un evento ha avuto luogo e chiunque lo ascolta che gestirà l'evento lo fa. In questo modo si disaccoppiano gli eventi realmente accaduti con ciò che li sta ascoltando. (Registrazione, segnali, ecc.)

Visitatore

La cosa brutta che trovo su questo, a parte il fatto che gli sviluppatori non riescono a pensare a nomi significativi e chiamano solo metodi visit (), è che aggiunge estensibilità in una direzione mentre la rimuove in un'altra, cioè aggiunge funzionalità extra ma limita il numero di oggetti di cui i visitatori hanno bisogno per conoscere tutti i tipi di oggetti che possono visitare.

È possibile, sebbene disordinato, consentire l'estensione in entrambe le direzioni, ma ciò non utilizza totalmente il modello di visitatore nella sua forma normale. L'applicazione più comune per questo è la stampa di oggetti: hai diversi modi per stampare oggetti e diversi oggetti che devono essere stampati. Dovresti essere in grado di estenderlo in entrambe le direzioni. (Stampa significa qualsiasi tipo di trasformazione di oggetti in un flusso: memorizzazione in un file/scrittura su una console/GUI ... ecc.).

(Nota: non dovresti confonderlo con l'architettura di visualizzazione del documento, che è un modello leggermente diverso).

2
CashCow

Penso che il problema con alcuni dei modelli più complessi sia che ci sono così tante variazioni su di loro che perdono gran parte del loro valore come dispositivo di comunicazione.

Il peggior trasgressore che mi viene in mente in questa categoria è il modello MVC. Anche se ignoriamo MVP, ci sono così tante variazioni nei ruoli di ciascuno di questi elementi che devi passare un'ora in ogni nuovo framework per capire dove si trovano i confini.

2
Uri

Non ci sono cattivi schemi solo cattive persone.

Preferirei piuttosto ereditare un codice facilmente leggibile che fa qualcosa di chiaro ma che è un po 'prolisso (non mettere in coda la musica villian malvagia) riutilizzabile (sussulto!) Rispetto a qualche mash mash di InheritAbstractTemplateFaucetSink<Kitchen>.

Il codice riutilizzabile è fantastico! È probabile che tu non stia scrivendo codice che verrà riutilizzato o riscrivendo una logica simile per un'altra applicazione richiederebbe meno tempo di un tentativo folle di riutilizzare il codice di un'altra applicazione.

Per ulteriori letture, apri un po 'del codice C nelle implementazioni sane delle intestazioni posix o dei clibs e gioca a punto il modello. Questo codice è stato scritto da alcuni dei programmatori più intelligenti e dedicati al mondo. Sai quanti schemi di fabbrica astratti vedrai? ... NESSUNO !. Le possibilità ancora migliori sono se capisci le altre parti di ciò che sta succedendo, troverai la logica molto facile da capire e tracciare.

Il mio punto è che la maggior parte dei "modelli" non sono stati creati per migliorare il codice, ma sono stati creati per vendere libri e software di modellazione. Se sei bravo a programmare probabilmente eviterai la maggior parte di questi e scriverai codice chiaro, conciso e progettato in modo intelligente che risolve il tuo problema. Quando hai un altro problema, scriverai un codice chiaro, conciso e abilmente progettato per risolverlo. Se il tuo obiettivo è scrivere meno codice di quello che penserei non saresti stato programmatore. Adoro scrivere codice e voglio scriverlo il più possibile. Quando riscrivo qualcosa che ho già scritto, lo faccio decine di volte più velocemente e riesco a sbarazzarmi di tutte le cose che non ero contento della prima volta che l'ho fatto. Come bonus, riesco a farlo senza nessuna delle limitazioni del primo set di problemi perché è un nuovo problema (probabilmente ho 15 script in 5 lingue diverse che fanno girare Tomcat).

Con ciò ti lascerò probabilmente la migliore (pertinente) citazione in informatica.

"Esistono due modi per costruire un progetto software: un modo è renderlo così semplice che non ci siano ovviamente carenze, e l'altro è renderlo così complicato che non ci sono carenze evidenti. Il primo metodo è molto più difficile. "

  • Tony Hoare (inventore del quicksort, padre della progettazione di sistemi operativi moderni, creatore della logica Hoare e vincitore del premio Turing)
1
nsfyn55

Sono assolutamente d'accordo che c'è un tempo per la maggior parte degli schemi e che puoi abusare di molti schemi. So che quello che ho abusato di più in passato è il modello di modello astratto. Presa al massimo, è nota come webforms ASP.NET.

0
Wyatt Barnett