Tecniche di programmazione abusate o abusate [chiuso]


38

Ci sono delle tecniche di programmazione che ritieni siano state abusate (IE ha usato in modo più eccessivo di quello che dovrebbero essere) o abusate, o usate un po 'per tutto, pur non essendo una soluzione davvero buona a molti dei problemi che le persone tentano di risolvi con esso.

Potrebbero essere espressioni regolari, una sorta di modello di progettazione o forse un algoritmo o qualcosa di completamente diverso. Forse pensi che le persone abusino di eredità multipla ecc.


33
Sono d'accordo che IE è usato in modo più eccessivo di quanto dovrebbe essere, ma questo è principalmente da non programmatori. . .
Eric Wilson,

7
@FarmBoy - Penso che intendesse IE: "Ie" sta semplicemente per "cioè", che scritto completamente in latino è 'id est'.
Raphael,

Risolto il problema :)
Anto,

4
Qualsiasi tecnica può (e spesso viene abusata), deve solo essere presentata come il prossimo proiettile d'argento e troverai qualcuno che tratta ogni problema come un chiodo (per mescolare metafore).
ChrisF

8
@Rapheal - Stavo scherzando, ovviamente. Grazie per l'educazione.
Eric Wilson,

Risposte:


73

Commenti nel codice

Vorrei solo che i professori universitari capissero che non avevano bisogno di insegnare ai loro studenti a scrivere 10 righe di commenti dicendo che il seguente codice è un ciclo for, che scorre da 1 a numero di x. Lo vedo nel codice!

Insegnate loro a scrivere prima il codice autodocumentante, quindi commentando adeguatamente ciò che non può essere adeguatamente autodocumentato secondo. Il mondo del software sarebbe un posto migliore.


26
Il codice autocompensante non lo è. Anche i professori lo fanno per insegnare agli studenti a concettualizzare il problema e come affrontarlo. Inoltre, non ho mai visto nessuno lamentarsi di troppa documentazione. L'avvertenza è che la documentazione è corretta.
Woot4Moo,

24
@ Woot4Moo: se leggi Clean Code, Fowler afferma chiaramente che la documentazione non aggiornata è peggio di nessuna documentazione e che tutti i commenti hanno la tendenza a diventare obsoleti e a migrare lontano dal codice che documentano. L'intero libro è tutto su come scrivere il codice di auto-documentazione.
Scott Whitlock,

12
Insegnare loro a sostituire i commenti con il codice sarebbe un buon inizio ...
Shog9

15
+1. In realtà ho visto quanto segue nel codice del mondo reale: "loopVar ++; // increment loopVar". AAAAAAAAAAAAARRRRRGH!
Tavoli Bobby,

7
@Bill: la mia opinione è che non dovresti aver bisogno di documentare la logica generica e le strutture di controllo, anche se sono relativamente complesse. Fondamentalmente, tutto ciò che un buon sviluppatore che conosce la lingua dovrebbe essere in grado di elaborare analizzando il codice non dovrebbe essere commentato. per esempio. Un insieme di loop nidificati con alcune interruzioni al loro interno, ecc. Ma ciò che DOVREBBE essere commentato è il ragionamento specifico dell'applicazione del perché il codice prende quelle decisioni: ad es. "Se domani un nuovo programmatore inizia in azienda e guarda il codice, cosa ha senso senza i suggerimenti?"
Tavoli Bobby,

57

Il modello di design singleton.

Certo, è un modello utile ma ogni volta che un nuovo programmatore viene a conoscenza di questo modello, inizia a provare ad applicarlo su ogni singola classe che crea.


Uso questa scusa mal progettata per un quadro ogni giorno. codeigniter.com/user_guide/libraries/email.html Pensano che OOP abbia il prefisso con le funzioni $this->. PHP è un linguaggio marcio, quindi non posso aspettarmi che i framework siano eccellenti.
Keyo,

7
Penso che qualsiasi programmatore che implementa un singleton e che non si pente brucerà in un inferno infuocato per i peccati che ha commesso.

2
Ho implementato un singleton una volta nella mia carriera professionale (in un contesto multitasking) e ho dovuto pentirmi per il mio peccato riscrivendolo.
Spoike,

3
I singleton possono essere utili per alcune cose, ma sono quasi sempre usati quando non dovrebbero esserlo. Ciò non significa che i singoli non dovrebbero mai essere usati - solo perché qualcosa viene abusato non significa che non possa essere usato correttamente.
configuratore

2
@Rapahel: Questo è esattamente il motivo per cui non credo che studiare modelli di design sia una buona cosa.
configuratore

53

La cosa più cattiva per proteggere la programmazione stupida. mettere tutto in una presa e non fare nulla con la presa

        try
        {
            int total = 1;
            int avg = 0;
            var answer = total/avg;
        }
        catch (Exception)
        {

        }

Rabbrividisco quando vedo un tentativo di cattura che non fa nulla ed è progettato per gestire una logica stupida. In generale, le catture di prova sono troppo utilizzate, tuttavia in alcuni casi sono molto utili.


4
Cosa divertente - Ho appena modificato un file che lo fa centinaia di volte, e con buone ragioni. È un file di test unitario, che verifica che vari metodi generino un'eccezione quando previsto. Il blocco try contiene una chiamata e un rapporto "lancio previsto non accaduto". L'eccezione è prevista e corretta, quindi non è prevista alcuna azione correttiva. Ovviamente i test unitari sono un caso speciale, ma ho avuto casi simili in codice reale. Bandiera rossa, sì, ma non una regola assoluta.
Steve314,

5
@Sveve il caso che hai descritto è una rara condizione del bordo. Un altro che mi viene in mente è la registrazione del codice: se la registrazione stessa fallisce, non ha senso provare a registrare l'eccezione o interrompere l'app.
dbkk,

1
@dbkk - concordato sulla condizione limite e aggiungerei che quando hai davvero bisogno di catturare un'eccezione ma non hai bisogno di un'azione correttiva, aggiungendo un commento nel blocco catch per spiegare che è essenziale se non altro per calmare il manutentori. Non è così raro nei test unitari, quindi lascerei cadere il commento in quel caso.
Steve314,

5
in caso di errore riprendere successivo
jk.

2
@ jk01 - un'eccezione non è (necessariamente) un errore. Se una condizione è un errore o meno dipende dal contesto. Ad esempio, "file non trovato" non è un errore se non è necessario il file. Forse è solo un file di impostazioni facoltativo che può essere o non essere presente e puoi semplicemente lasciare le impostazioni predefinite se il file non è presente (quindi non è necessaria alcuna azione correttiva dopo la cattura).
Steve314,

47

Affidati a StackOverflow per risolvere i tuoi problemi invece di capirlo nel modo più duro.

Nuovi programmatori che trovano la ricchezza di conoscenze sui post SO (troppo spesso) prima di pensare e provare cose.

Ai miei tempi dovevamo programmare da libri, niente internet, niente SO. Adesso vattene dal mio prato.


28
Devo ammettere che sussulto all'audacia di alcune domande su SO. O perché vengono richiesti molte volte ogni giorno e ovviamente non hanno cercato affatto; o peggio ancora, trattano la comunità come un servizio di outsourcing gratuito.
Orbling

2
@dbkk: stackoverflow.com/questions/4665778/... -> primo commento "Hai mai provato questo?"
Matthieu M.

5
Ho iniziato ad imparare dai libri ma una volta che ho avuto un fondamento ho imparato quasi tutto il resto dalle discussioni del forum online. Non chiedendo, ma principalmente (e inizialmente, esclusivamente) leggendo. Questo metodo mi ha insegnato diversi linguaggi di programmazione in profondità lancinante (con molti angoli e fessure), e penso che non sia affatto un cattivo metodo.
Konrad Rudolph,

1
@Konrad Rudolph: questo metodo è buono e saggio, leggere domande, cercare bene. La domanda viene fatta meglio quando il richiedente ha una struttura con cui comprendere le risposte. Troppo spesso le persone fanno domande che non hanno (ancora) la capacità di comprendere.
Orbling

3
il problema è che SO incoraggia questo dando un sacco di rappresentanti per porre / rispondere a domande molto facili a cui si può rispondere con una semplice ricerca su Google. domanda molto difficile a cui le persone rispondono solo perché vogliono davvero.
IAdapter

36

OOP evidentemente. È molto prezioso, ma se usato in modo improprio può oscurare il codice altrimenti abbastanza facilmente (mi vengono in mente alcuni esempi di programmazione S4 in R) e può dare un enorme sovraccarico che non è necessario e può costare molto tempo per le prestazioni.

Un'altra cosa è che (ad esempio Perl) OOP spesso si riduce a scrivere la stessa cosa al contrario: result = $object ->function(pars)invece di result = function(object, pars)Questo a volte ha senso, ma se combinato con la programmazione procedurale può rendere la lettura del codice piuttosto confusa. E a parte questo, si introduce solo un overhead in cui non migliora il design. Dipende anche da ciò che viene detto sul modello singleton: dovrebbe essere usato, ma non su tutto.

Uso OOP da solo, ma nel mio campo (calcolo scientifico) le prestazioni sono un grosso problema, e OOP è spesso abusato lì come tutti gli studenti ottengono Java al giorno d'oggi. È ottimo per affrontare problemi più grandi, per concettualizzare e così via. Ma se lavori con sequenze di DNA ad esempio in BioPerl, usare gli oggetti ogni volta e lavorare in modo coerente con getter e setter può aumentare di dieci volte il tempo di calcolo. Quando il codice viene eseguito per alcuni giorni anziché per alcune ore, questa differenza conta davvero.


6
@Craige: Uso OOP da solo, ma nel mio campo (calcolo scientifico) le prestazioni sono un grosso problema e OOP viene spesso abusato lì poiché tutti gli studenti ottengono Java al giorno d'oggi. È ottimo per affrontare problemi più grandi, per concettualizzare e così via. Ma se lavori con sequenze di DNA ad esempio in BioPerl, usare gli oggetti ogni volta e lavorare in modo coerente con getter e setter può aumentare di dieci volte il tempo di calcolo. Quando il codice viene eseguito per alcuni giorni anziché per alcune ore, questa differenza conta davvero .
Joris Meys,

1
@Craige: concatenare il metodo (come Foo.DoX().DoY().DoZ()) è bello, ma, sicuramente, non è l'unico modo per fare qualcosa. Composizione della funzione (come doZ . doY . doX $ fooè un'alternativa perfettamente valida.
Anon.

1
@Joris: qualcosa che mi chiedevo da molto tempo (me stesso un bioinformatico): se le prestazioni contano così tanto, perché usare Perl al posto del C ++? Se sei preoccupato di radere via un fattore 10 dal tempo di esecuzione (preoccupazione valida!), Passare a C ++ ti dà una gratificazione immediata. Certo, il linguaggio fa schifo ... ma poi, così fa Perl ... e ci sono buone librerie bioinformatiche per C ++.
Konrad Rudolph,

1
@Konrad: dipende. BioPerl ha probabilmente il maggior numero di pacchetti per bioinformatici di tutte le lingue (credo che Python stia recuperando terreno). Inoltre, in Perl è stato svolto molto lavoro e adattare uno script è più semplice che riscrivere tutto in C ++. Infine, non serve a scrivere un'applicazione completa quando uno script lo farà. Immagino sia per questo che Perl è ancora così tanto in giro. E onestamente, non mi dispiace, mi piace la lingua. È ancora il migliore che conosca per il lavoro su stringhe e file. I calcoli sono ovviamente fatti in altre lingue e collegati indietro (il che è abbastanza semplice).
Joris Meys,

1
@Konrad: dipende da come si fa. È possibile fare tutto in Perl, ma Perl può essere facilmente collegato ad altri strumenti, specialmente su Linux. Uso spesso Perl come uno script bash avanzato con una forte manipolazione delle stringhe e una facile costruzione di set di dati da inserire in altre applicazioni.
Joris Meys,

27

Avendo trascorso diversi anni nei moduli Web ASP.NET, dovrei dire inequivocabilmente:

L'interfaccia utente intelligente

Mentre è del tutto possibile creare applicazioni stratificate e testabili in moduli web, Visual Studio rende troppo facile per gli sviluppatori fare un clic per ottenere moduli strettamente legati alla loro origine dati, con la logica dell'applicazione disseminata su tutto il codice dell'interfaccia utente.

Steve Sanderson spiega questo anti-pattern molto meglio di quanto potrei nel suo libro Pro ASP.NET MVC:

Per creare un'applicazione Smart UI, uno sviluppatore prima costruisce un'interfaccia utente, in genere trascinando una serie di widget dell'interfaccia utente su un'area di disegno, quindi riempie il codice del gestore eventi per ogni possibile clic sul pulsante o altro evento dell'interfaccia utente. Tutta la logica dell'applicazione risiede in questi gestori di eventi: logica per accettare e convalidare l'input dell'utente, eseguire l'accesso e la memorizzazione dei dati e fornire feedback aggiornando l'interfaccia utente. L'intera applicazione è composta da questi gestori di eventi. In sostanza, questo è ciò che tende a venire fuori per impostazione predefinita quando metti un principiante davanti a Visual Studio. In questo progetto, non vi è alcuna separazione delle preoccupazioni. Tutto viene fuso insieme, organizzato solo in base ai diversi eventi dell'interfaccia utente che possono verificarsi. Quando le regole logiche o aziendali devono essere applicate in più di un gestore, il codice viene generalmente copiato e incollato, o alcuni segmenti scelti a caso vengono fattorizzati in classi di utilità statiche. Per tanti ovvi motivi, questo tipo di motivo di design è spesso chiamato anti-pattern.


1
Una GUI è almeno una sorta di codice di specifica che deve rispettare. Non credo che i programmatori che descrive farebbero meglio se presentati con un file di testo vuoto.

4
@qpr, non lo so. Se avessero un file di testo vuoto potrebbero non essere in grado di fare nulla (che potrebbe essere solo un bonus).
Ken Henderson,

Uno dei molti vantaggi dell'utilizzo di WPF è che l'implementazione di MVVM fa a pezzi questo anti-schema.
Robert Rossney,

2
Mille volte questo. Vedo persino sviluppatori .NET esperti fare affidamento su questo "modello" perché è più facile della comprensione o della cura della separazione delle preoccupazioni. Anche se non usano le procedure guidate di trascinamento della selezione, il "modello" più comune nello sviluppo di .NET WebForms è fare tutto negli eventi code-behind e copiare / incollare il codice secondo necessità.
Wayne Molina,

23

Lo vedo di tanto in tanto e di solito deriva dal non comprendere appieno le espressioni booleane.

if (someCondition == true)

16
Ha il vantaggio di rendere il codice più esplicito
Pemdas,

7
Penso che uno sguardo a questa domanda sia in ordine: programmers.stackexchange.com/questions/12807/…
gablin

5
Non lo faccio ma, sul serio, lo supero. C'è molto di peggio là fuori. :)
MetalMikester,

4
Se le variabili sono state denominate correttamente, ad esempio booliniziando con iso has, non è necessario rendere il codice più esplicito con = true.
Nessuno il

3
@DisgruntledGoat perché non dovrebbe essere affatto in uso
Corey

19

Reimplementazione della funzionalità di base (o altrimenti fornita), a causa dell'ignoranza della sua esistenza o a causa di un bisogno percepito di personalizzazioni.


2
L'apprendimento è un'eccezione. Quando si studia qualcosa, è spesso utile "reinventare la ruota".
Maxpm

Di sicuro - avrei dovuto specificare che è rilevante solo durante la creazione di software di produzione.
20

1
Ciò è particolarmente negativo quando si implementa qualcosa relativo alla sicurezza. Un buon software di sicurezza impedisce attacchi a cui la maggior parte delle persone non pensa nemmeno.
David Thornley,

Vedo in questo modo troppo comune. Abbiamo bisogno di X, scriviamo il nostro! Ma per quanto riguarda il pacchetto open source Y? No, abbiamo bisogno di software personalizzato per i nostri segreti commerciali super segreti che sono gli stessi di tutti gli altri nel nostro settore, non possiamo usare un comune software per la spazzatura!
Wayne Molina,

18

Eredità.

Non forzare is-a dove non ha senso.


6
Il problema è che intuitivamente “is-a” sembra molto spesso avere senso (in particolare poiché ogni relazione di implementazione / contratto può essere espressa colloquialmente come “is-a”). Richiede una solida conoscenza di OOP per rendersi conto che questo è in realtà un errore e che l'ereditarietà e l'implementazione dell'interfaccia sono fondamentalmente diverse.
Konrad Rudolph,

@Konrad - d'accordo assolutamente. Cerco di incoraggiare le persone a iniziare con la composizione , passare alle interfacce e considerare l'ultima eredità. (Di regola, ovviamente). Ma forse è questo il mio background VB che parla ... ;-)
Mike Woodhouse il

1
Questa, tuttavia, è in gran parte una questione di design del linguaggio. Il motivo per cui dovresti "preferire la composizione rispetto all'ereditarietà (dell'implementazione)" in linguaggi come Java o C #, è perché l'ereditarietà dell'implementazione risucchia in quei linguaggi. Alcune persone criticano la costruzione di software orientato agli oggetti di Bertrand Meyer per l'uso eccessivo dell'ereditarietà, ma quando guardi effettivamente Eiffel (il linguaggio usato nel libro), ti rendi conto che è stato progettato per l'ereditarietà dell'implementazione , e quindi in realtà va bene usare l'ereditarietà composizione. In quel caso, almeno.
Jörg W Mittag,

14

Personalizzazione del software standard.

Mentre posso riconoscere che questo può essere utile, mi chiedo quanti soldi vengono spesi per fare piccole cose per guadagni discutibili. È qui che un'azienda può spendere centinaia di migliaia se non milioni di dollari in licenze per alcuni software che vengono quindi personalizzati perché è così configurabile, modificabile e flessibile che in realtà non fa molto per impostazione predefinita. Alla fine si tratta di un'applicazione personalizzata a causa di tutto il nuovo codice aggiunto ciò che è stato inizialmente acquistato.


Non è più probabile che ciò avvenga con un'applicazione personalizzata?
JeffO,

13

Utilizzo del compilatore come debugger.

Ignorando gli avvisi del compilatore o spegnendoli completamente.

Variabili globali.


18
Cosa c'è di sbagliato nell'uso del compilatore come debugger? Avere un compilatore in grado di segnalare errori nel codice prima che diventino un problema in fase di esecuzione è un enorme vantaggio.
Mason Wheeler,

3
Mi affido al compilatore che rileva i miei errori di sintassi e errori di corrispondenza dei tipi errati. Per errori comportamentali, faccio affidamento su casi di test.
gablin,

5
Il problema è quando si inizia a dipendere dal compilatore per garantire la correttezza del programma. Questo è stato compilato? No, permettimi di approfondire questa piccola sezione e vedere se è stato risolto. Si è compilato? No, lasciami aggiungere un * qua e là e vedere se compila. ... ect. Ovviamente, è utile per correggere errori di battitura
Pemdas,

2
Dici che come se il programmatore stesse frugando ciecamente nel buio cercando di fare qualcosa, qualunque cosa, per ottenere la compilazione del codice. Non è così che funziona l'IME; il compilatore ti dà un utile messaggio di errore e ti indica la posizione dell'errore, e di solito se qualcosa non sta compilando è il nuovo codice che hai scritto tu stesso, quindi hai una buona idea di cosa c'è che non va e come risolverlo una volta che è stato indicato su. (Anche se stai lanciando casualmente * s, potresti lavorare in C ++, dove gli errori del compilatore sono noti per essere estremamente inutili, quindi quello che ho detto potrebbe non essere applicabile.)
Mason Wheeler,

3
Affidarsi al compilatore funziona molto bene, dato un sistema di tipi abbastanza forte e una base di codice ben tipizzata. Spesso, il sistema dei tipi può modellare vincoli importanti per i quali altrimenti dovresti scrivere dei test (ad esempio nei sistemi debolmente tipizzati). Così usato con giudizio, il compilatore (e in particolare il suo tipo di controllo) è una grande risorsa per i test e il debug e non c'è niente di sbagliato nel fare affidamento su di esso. In particolare, è sbagliato affermare che un compilatore può mostrare solo errori di sintassi.
Konrad Rudolph,

11

Tutti i modelli di design.

Sono come sale o zucchero. Alcuni sul tuo cibo lo rendono fantastico, molti altri fanno schifo il tuo cibo.

Non fraintendetemi. I modelli di progettazione sono tecniche meravigliose. Li ho usati molto. Ma a volte trovo programmatori, (alcuni dei quali sono i miei ex capi), che avevano questi "devi usare un modello di progettazione", anche se non corrisponde al problema !!!

Un esempio è il "modello di visitatore" che è più diretto per "Collezioni lineari / sequenziali". Una volta ho dovuto lavorare con una struttura di dati ad albero. Per "visitare" ogni articolo, codifico un metodo di modello non di progettazione e un ex capo insiste per usare o adattare il "Modello di visitatore". Quindi, navigo in rete, per un secondo parere. Bene, altri programmatori avevano la stessa situazione e la stessa soluzione. E chiamalo "Tree / Hierarchical Visitor Pattern"., Come un NUOVO Design Pattern

Spero che sia aggiunto come nuovo modello a quelli esistenti, in una nuova versione del libro "Design Patterns".


3
Non uso mai modelli di design, anche se a volte emergono naturalmente nel mio codice.
configuratore

Come va il proverbio? Inizi a usare i pattern senza sapere che li stai usando, poi li impari e li usi ovunque, poi diventano una seconda natura, quindi inizi a usarli senza sapere che li stai usando?
Wayne Molina,

2
@configurator Quando ho letto degli schemi di progettazione;
Scopro

9

Utilizzo delle eccezioni come controllo del flusso. Un po 'simile a questa risposta , ma diverso.

Ingoiare eccezioni è una cattiva forma perché introduce nel codice bug misteriosi e difficili da trovare. L'uso delle eccezioni come controllo di flusso, d'altra parte, è negativo perché rende il codice molto più inefficiente di quanto potrebbe essere ed è concettualmente sciatto.

La gestione delle eccezioni dovrebbe essere utilizzata solo per gestire scenari davvero eccezionali (duh) e imprevisti, non cose come un utente che digita un carattere alfabetico in cui è previsto un numero. Questo tipo di abuso delle eccezioni è estremamente comune tra i programmatori inadeguati nel mondo Java.


Le eccezioni che determinano un codice inefficiente dipendono dalla tua lingua - creazione di uno stack frame ecc. Ecc. In Squeak, lo stack è completamente reificato, quindi non c'è alcuna differenza tra l'utilizzo di eccezioni o meno. (In altre parole, le eccezioni fanno parte della libreria, non della lingua.) Tuttavia, è confuso lavorare con un flusso di controllo controllato dalle eccezioni: lshift.net/blog/2011/01/04/try-again-with-exceptions shows un loop-using-eccezioni che ho trovato di recente.
Frank Shearar,

Per quanto riguarda l'ultimo paragrafo, dipende ancora dalla tua lingua. Le eccezioni ("condizioni") in Common Lisp sono un rigido superset delle idee di eccezioni della maggior parte delle lingue. Vedi esempi qui: gigamonkeys.com/book/… Come per tutto, puoi andare troppo lontano!
Frank Shearar,

La leggibilità e la manutenibilità sono superiori alle prestazioni. I casi in cui userò eccezioni per il successo (cosa presumo intendi per "controllo del flusso") sono molto rari, ma possono fornire un codice più pulito in una complessa ricerca ricorsiva. In generale, sono d'accordo però. Ad esempio, ho contenitori con metodi iteratori che restituiscono false per uscire dall'intervallo (comune alla fine di un'iterazione), ma lancio un'eccezione se l'iteratore è "null" (un probabile segno di qualche tipo di incoerenza interna)
Steve314,

7

Vado con inflessibilità attraverso un eccessivo nascondimento dei dati.

Sappiamo tutti che l'astrazione e nascondere l'implementazione sono buone, ma di più non è sempre meglio. Esagerato, è possibile ottenere un risultato non flessibile che non è in grado di far fronte alle modifiche dei requisiti. Per gestire la modifica, non è necessario solo modificare la classe che deve gestire tale modifica, ma è anche necessario creare un modo per rendere accessibili le informazioni che non sono mai state necessarie prima nonostante i livelli di occultamento dei dati.

Il problema è che, come per tutte le questioni relative al trovare il giusto equilibrio per ogni contesto, ci vuole esperienza.



6

Stato mutevole e loop. Non hai quasi mai bisogno di loro e quasi sempre ottieni un codice migliore senza di loro.

Ad esempio, questo viene preso direttamente da un thread StackOverflow:

// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
    thing = things[i];
    if(things_by_type[thing.type]) {
        things_by_type[thing.type].push(thing);
    } else {
        things_by_type[thing.type] = [thing];
    }
}

# Ruby
things_by_type = {}
things.each do |thing|
  (things_by_type[thing.type] ||= []) << thing
end

Stanno entrambi facendo la stessa cosa. Ma non ho idea di cosa stiano facendo. Fortunatamente, la domanda in realtà spiega cosa stanno facendo, quindi sono stato in grado di riscriverli come segue:

// ECMAScript
things.reduce(function (acc, thing) {
    (acc[thing.type] || (acc[thing.type] = [])).push(thing);
    return acc;
}, {});

# Ruby
things.group_by(&:type)

// Scala
things groupBy(_.type)

// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);

Non ci sono anelli e nessuno stato mutabile. Bene, ok, nessun loop esplicito e nessun contatore di loop.

Il codice è diventato molto più breve, molto più semplice, molto più simile a una descrizione di ciò che il codice dovrebbe fare (specialmente nel caso di Ruby dice praticamente direttamente "raggruppa le cose per tipo") e molto meno soggetto a errori. Non c'è pericolo di scappare dalla fine dell'array, errori di fencepost o errori off-by-one con gli indici di loop e le condizioni di terminazione, perché non ci sono indici di loop e condizioni di terminazione.


Credo che nella seconda riga del tuo ECMAScript "fisso" dovrebbe leggere (acc[thing.type] || (acc[thing.type] = [])), al contrario di `= [cosa] , unless you want to add cosa` nell'elenco due volte ... O mi sto perdendo qualcosa?
Austin Hyde,

@Austin Hyde: hai ragione.
Jörg W Mittag,

1
Quell'esempio di ecmascript è incomprensibile per molti programmatori. Si basa su troppi trucchi sintattici. Il ciclo ha il vantaggio dell'ovvietà per gli sviluppatori junior.
Joeri Sebrechts,

6

Beffardo. Presenta troppi requisiti artificiali per l'eccessivo disaccoppiamento nel codice, porta a ravioli troppo ingegnerizzati e ti costringe a progettare in stile OO in gola quando un design più procedurale o funzionale potrebbe essere una soluzione più semplice al tuo problema.


Concordato in teoria; mock sono utili ma non si hanno per averli.
Wayne Molina,

L'invasività del deridere dipende dalla lingua che usi. In C #, può essere molto invasivo e aggiunge una serie di interfacce non necessarie.
Frank Hileman,

3

I programmatori Delphi di tutto il mondo hanno scoperto negli ultimi due anni quanto sia male usare gli array di caratteri per memorizzare byte a causa della conversione Unicode wholescale

E "presto" impareremo quanto è male archiviare numeri interi negli elenchi quando vogliamo apportare la modifica a 64 bit.


2
Penso che una grande parte dei problemi di Unicode non sarebbe mai emersa se Borland avesse dichiarato un tipo di DataString che era sostanzialmente lo stesso di AnsiString ma specificamente per l'uso con i BLOB, e poi si assicurava che le persone lo sapessero.
Mason Wheeler,

2

Proprietà. So che questo è controverso, ma sento che le proprietà sono ampiamente abusate in .net.

Qual è la differenza tra queste due linee?

public string Property { get; set; }

public string Field;

Per lo sviluppatore, la differenza è: assolutamente niente. Il modulo compilato è leggermente diverso, quindi se stai scrivendo una libreria e quella libreria verrà aggiornata nei programmi e non puoi ricompilare i programmi stessi (ad esempio se stai scrivendo un'interfaccia per plugin che dovrebbe funzionare su più versioni del software), quindi non utilizzare campi pubblici perché non è possibile sostituirli con proprietà. In ogni altro caso, non c'è assolutamente alcuna differenza tra l'utilizzo di un campo o una proprietà automatica senza modificatori.


1
Concordato; se conosci il 100% non dovrai mai fare nulla per ottenere / impostare una "proprietà", quindi non c'è alcun motivo per avere una proprietà. Tuttavia, se esiste la possibilità che tu debba fare qualcosa (registrando che un valore è stato modificato, ad esempio), dovresti usare una proprietà. Personalmente non vedo una grande differenza abbastanza per non utilizzare la proprietà, nel caso in cui si fa necessità di modificare in un secondo momento (lo so, lo so YAGNI, ma mi sento deviare in questo caso non costa nulla)
Wayne Molina

2
@Wayne: Come sta cambiando ;ad { get { ... } set { ... } }ogni più lavoro che cambia { get; set; }a { get { ... } set { ... } }?
configuratore

Ora che ci penso, questo è un punto giusto.
Wayne Molina,
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.