Quali modelli di design sono i peggiori o i più limitati? [chiuso]

28

Per ogni progetto di programmazione, i manager con esperienza di programmazione passata cercano di brillare quando raccomandano alcuni modelli di progettazione per il tuo progetto. Mi piacciono i modelli di design quando hanno senso o se hai bisogno di una soluzione scalabile. Ad esempio, ho usato i pattern Proxy, Osservatori e Comando in modo positivo, e lo faccio ogni giorno. Ma sono davvero titubante nell'usare un pattern Factory se c'è un solo modo per creare un oggetto, dato che una fabbrica potrebbe rendere tutto più semplice in futuro, ma complica il codice ed è puro overhead.

Quindi, la mia domanda riguarda la mia futura carriera e la mia risposta ai tipi di manager che lanciano nomi di pattern casuali in giro:

Quali modelli di design hai utilizzato, che ti hanno respinto in generale? Quali sono i peggiori schemi di progettazione , quelli che dovresti prendere in considerazione tranne che nella singola situazione in cui hanno senso (leggi: quali schemi di progettazione sono definiti in modo molto ristretto)? (È come se stavo cercando le recensioni negative di un buon prodotto di Amazon per vedere cosa ha infastidito maggiormente le persone nell'uso di modelli di design.) E non sto parlando di Anti-Pattern qui, ma di Pattern che sono generalmente considerati come modelli "buoni".

Modifica: come alcuni hanno risposto, il problema è più spesso che i pattern non sono "cattivi" ma "usati sbagliati". Se si conoscono modelli, che sono spesso utilizzati in modo improprio o persino difficili da usare, si adatterebbero anche come risposta.

    
posta Akku 17.02.2011 - 07:55
fonte

12 risposte

39

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

  • IMHO il singleton è il modello più abusato e più erroneamente applicato. Le persone sembrano avere una malattia singleton e iniziare a vedere le possibilità di singleton ovunque senza considerare alternative.
  • IMHO modello di visitatore ha l'uso più ristretto e quasi mai la complessità aggiunta sarà giustificata. Un bel pdf può essere ottenuto qui . In realtà, solo quando hai una struttura dati che sai essere attraversata mentre fai diverse operazioni sulla struttura dati senza conoscere tutti i modi in anticipo, dai al visitatore una possibilità di combattere. È carino però:)

Per questa risposta ho considerato solo i modelli GOF. Non conosco tutti i possibili schemi abbastanza bene da tenerli in considerazione anche.

    
risposta data 17.02.2011 - 10:00
fonte
14

Oltre a Singleton e Visitor già menzionati dagli altri rispondenti, non conosco schemi di design "famigerati". IMHO i problemi più grandi non derivano dal fatto che uno specifico pattern di progettazione sia "sbagliato", ma piuttosto dagli sviluppatori che applicano i pattern troppo avidamente.

Quasi tutti seguono la fase della "febbre da modello" quando si familiarizzano con i modelli. Pensando che i modelli sono la cosa migliore dopo il pane a fette, inizialmente si cerca di applicarli ogni volta che vede una possibilità. Il risultato è che il codice viene nascosto sotto i modelli, in cui gli schemi stessi non aiutano più, basta rendere il codice più difficile da capire e mantenere a lungo termine.

Alla fine, molti di noi superano questa fase e iniziano a imparare come usare i modelli per risolvere problemi reali, non per il loro stesso interesse. I pattern hanno il loro prezzo, che è una complessità aggiuntiva, e l'applicazione di uno specifico pattern è giustificata solo quando ripaga per la complessità aggiunta, aiutando a semplificare qualche altra parte del sistema, rendendo così il codice / configurazione nel complesso più facile da capire e mantenere. Se questo non è il caso, spesso è meglio stare lontano dai modelli, attenendosi alla soluzione più semplice che potrebbe funzionare.

    
risposta data 17.02.2011 - 10:23
fonte
14

Ho intenzione di uscire su un arto qui e suggerire l'uso eccessivo dell'eredità. Sicuramente più applicabile in lingue senza un solido supporto di polimorfismo in fase di compilazione, come Java. L'ereditarietà run-time è uno strumento, non una sorta di meraviglia di una sola caratteristica.

Altre persone hanno già espresso il mio stesso odio per Singletons, quindi non ho intenzione di approfondire qui.

    
risposta data 17.02.2011 - 14:34
fonte
10

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

    
risposta data 17.02.2011 - 09:31
fonte
7

If you know patterns, that are often misused or even difficult to use, they would also fit as an answer.

Seguendo il pattern MVVM per WPF troppo rigorosamente, come indicato ad esempio da questa domanda . Alcune persone cercano di seguire la linea guida secondo cui nessun codice dovrebbe essere inserito nel codice in modo troppo rigido e trovare tutti i tipi di hack esotici.

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

Dr. WPF ha scritto un post ironico nel suo articolo MV-poo .

    
risposta data 17.02.2011 - 13:09
fonte
5

Quello che rimpiango più spesso (anche se non molto con veemenza): Quando avrei dovuto creare una funzione, ma ho implementato una soluzione OOP.

    
risposta data 17.02.2011 - 13:29
fonte
4

Alcuni dei pattern nel libro GOF sono specifici per C ++, nel senso che sono meno applicabili nelle lingue con riflessione, ad es. il modello di Prototipo è meno significativo in Java.

Considero il pattern Interpreter come uno "stretto". Devi avere un problema generale che vale la pena sviluppare un risolutore di problemi generale. Funziona solo per problemi speciali per i quali puoi 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 capiti spesso in queste situazioni.

    
risposta data 17.02.2011 - 11:24
fonte
4

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

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

    
risposta data 17.02.2011 - 20:55
fonte
2

Singleton

Sono d'accordo con gli altri su Singleton. Non che non dovresti mai usarli, solo che dovrebbe essere limitato a pochissimi casi. Sono usati come globalmente pigri per molto tempo.

La sicurezza del thread è un problema con i singleton. La gestione delle eccezioni è un'altra: 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 del main". E poi c'è il problema di ripulire in seguito.

Io preferisco usare un singleton e avere tutti gli altri singleton "wannabe" "abbonati" al tuo. Il mio uso più comune di singleton è la gestione di "shout event": si "trasmette al mondo" solo che un evento è avvenuto e chiunque ascolti che gestirà l'evento lo farà. In questo modo si disaccoppiano gli eventi che effettivamente accadono con ciò che li ascolta. (Registrazione, segnali, ecc.)

Visitor

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

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

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

    
risposta data 17.02.2011 - 11:00
fonte
2

Penso che il problema con alcuni dei pattern più complessi sia che ci sono così tante varianti su di loro che perdono molto del loro valore come dispositivo di comunicazione.

Il peggior offensore che riesco a pensare in questa categoria è il pattern MVC. Anche se ignoriamo MVP, ci sono così tante variazioni nei ruoli di ognuno di questi elementi che devi passare un'ora in ogni nuovo quadro per capire dove si trovano i confini.

    
risposta data 18.02.2011 - 01:41
fonte
1

Non ci sono cattivi modelli solo persone cattive.

Preferisco di gran lunga ereditare codice facilmente leggibile che fa qualcosa di chiaro ma è un po 'prolisso o meno (coda malvagia musica villiana) riutilizzabile (sussulto!) di qualche mish mash di InheritAbstractTemplateFaucetSink<Kitchen> .

Il codice riutilizzabile è fantastico! È probabile che tu non stia scrivendo il codice che verrà riutilizzato o che riscrivere la logica simile per un'altra applicazione ti 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 debite implementazioni delle intestazioni di posix o delle clib e gioca il pattern. Questo codice è stato scritto da alcuni dei programmatori più intelligenti e più dedicati al mondo. Sai quanti Pattern Factory astratti vedrai? ... NONE !. Anche le migliori possibilità sono se comprendi le altre parti di cosa sta succedendo, troverai la logica molto facile da capire e tracciare.

Il mio punto è che la maggior parte dei "pattern" non sono stati creati per rendere il codice migliore sono stati creati per vendere libri e software di modellazione. Se sei bravo a programmare probabilmente eviterai la maggior parte di questi e scriverai un codice chiaro, conciso e intelligente che risolva il tuo problema. Quando si ha un altro problema, si scriverà un codice chiaro, conciso, progettato in modo intelligente per risolvere il problema. Se il tuo obiettivo è scrivere meno codice di quanto pensassi, il tuo non essere tagliato per essere un programmatore. Adoro scrivere codice e voglio scriverlo il più possibile. Quando ri-scrivo qualcosa che ho già scritto, lo faccio decine di volte più veloce e riesco a sbarazzarmi di tutte le cose che non ero felice con la prima volta che l'ho fatto. Come bonus, riesco a farlo senza le limitazioni del primo problema impostato perché è un nuovo problema (probabilmente ho 15 script in 5 lingue diverse che avviano la navigazione di TomCat).

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

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

  • Tony Hoare (inventore del quicksort, padre del moderno design del sistema operativo, creatore della logica Hoare e destinatario del premio Turing)
risposta data 13.03.2012 - 14:30
fonte
0

Sono assolutamente d'accordo che c'è un tempo per la maggior parte dei modelli e che puoi abusare di molti modelli. So che quello che ho abusato di più in passato è il pattern Modello astratto. Preso per intero è conosciuto come webform ASP.NET.

    
risposta data 17.02.2011 - 21:18
fonte