Domanda

Per quanto ne so, nonostante gli innumerevoli milioni o miliardi spesi per formazione, linguaggi e strumenti OOP, l'OOP non ha migliorato la produttività degli sviluppatori o l'affidabilità del software, né ha ridotto i costi di sviluppo.Poche persone utilizzano l'OOP in senso rigoroso (poche persone aderiscono o comprendono principi come LSP);sembra esserci poca uniformità o coerenza negli approcci che le persone adottano per modellare i domini problematici.Troppo spesso la classe viene utilizzata semplicemente per il suo zucchero sintattico;inserisce le funzioni per un tipo di record nel proprio piccolo spazio dei nomi.

Ho scritto una grande quantità di codice per un'ampia varietà di applicazioni.Sebbene ci siano stati luoghi in cui la vera sottotipizzazione sostituibile ha svolto un ruolo prezioso nell'applicazione, questi sono stati piuttosto eccezionali.In generale, anche se a parole si parla di "riutilizzo", la realtà è che a meno che un pezzo di codice non lo faccia esattamente quello che vuoi che faccia, c'è pochissimo "riutilizzo" economicamente vantaggioso.È estremamente difficile progettare classi affinché siano estensibili nella giusta direzione, e quindi il costo dell'estensione è normalmente così elevato che il "riutilizzo" semplicemente non vale la pena.

Per molti aspetti, questo non mi sorprende.Il mondo reale non è "OO", e l'idea implicita in OO - ovvero che possiamo modellare le cose con una tassonomia di classi - mi sembra fondamentalmente errata (posso sedermi su un tavolo, su un ceppo di albero, sul cofano di un'auto , il grembo di qualcuno, ma nessuno di questi è una sedia).Anche se ci spostiamo verso ambiti più astratti, la modellazione OO è spesso difficile, controintuitiva e, in definitiva, inutile (si considerino i classici esempi di cerchi/ellissi o quadrati/rettangoli).

Allora cosa mi manca qui?Dov'è il valore dell'OOP e perché tutto il tempo e il denaro non sono riusciti a migliorare il software?

È stato utile?

Soluzione

Non ci sono prove empiriche che suggeriscano che l’orientamento agli oggetti sia un modo più naturale per le persone di pensare al mondo.Alcuni lavori nel campo della psicologia della programmazione dimostrano che l'OO non è in qualche modo più adatto di altri approcci.

Le rappresentazioni orientate agli oggetti non sembrano essere universalmente più o meno utilizzabili.

Non è sufficiente adottare semplicemente metodi OO e richiedere agli sviluppatori di utilizzarli, perché ciò potrebbe avere un impatto negativo sulla produttività degli sviluppatori, nonché sulla qualità dei sistemi sviluppati.

Tratto da "Sull'usabilità delle rappresentazioni OO" dalle Comunicazioni dell'ACM dell'11 ottobre 2019.2000.Gli articoli confrontano principalmente l'OO con l'approccio orientato ai processi.Esistono molti studi su come "pensano" le persone che lavorano con il metodo OO (Int.J.of Human-Computer Studies 2001, numero 54, o Human-Computer Interaction 1995, vol.10 ha un intero tema sugli studi OO) e da quello che ho letto, non c'è nulla che indichi una sorta di naturalezza nell'approccio OO che lo renda più adatto di un approccio procedurale più tradizionale.

Altri suggerimenti

Il mondo reale non è "OO", e l'idea implicita in OO (che possiamo modellare le cose con una qualche tassonomia di classe) mi sembra fondamentalmente errata

Anche se questo è vero ed è stato osservato da altre persone (prendiamo Stepanov, l'inventore dell'STL), il resto non ha senso.L'OOP può essere difettoso e certamente non è una soluzione miracolosa, ma rende le applicazioni su larga scala molto più semplici perché è un ottimo modo per ridurre le dipendenze.Naturalmente, questo vale solo per il “buon” design OOP.Il design sciatto non darà alcun vantaggio.Ma un buon design disaccoppiato può essere modellato molto bene utilizzando l'OOP e non bene utilizzando altre tecniche.

Esistono modelli molto migliori e più universali (Modello tipo Haskell mi viene in mente) ma questi sono spesso anche più complicati e/o difficili da implementare in modo efficiente.L'OOP è un buon compromesso tra gli estremi.

L'OOP non riguarda la creazione di classi riutilizzabili, ma la creazione di classi utilizzabili.

Troppo spesso, la classe viene utilizzata semplicemente per il suo zucchero sintattico;esso inserisce le funzioni per un tipo di record nel loro piccolo spazio dei nomi.

Sì, trovo che anche questo sia troppo diffuso.Questa non è programmazione orientata agli oggetti.È programmazione basata su oggetti e programmazione incentrata sui dati.Nei miei 10 anni di lavoro con OO Languages, vedo persone che si occupano principalmente di programmazione basata su oggetti.OBP si rompe molto rapidamente IMHO poiché essenzialmente stai ottenendo il peggiore di entrambe le parole:1) Programmazione procedurale senza aderire a una metodologia di programmazione strutturata comprovata e 2) OOP senza aderire a una metodologia OOP comprovata.

L'OOP fatto bene è una cosa bellissima.Rende i problemi molto difficili facili da risolvere e, per chi non lo sapesse (non cercando di sembrare pomposo), può quasi sembrare magico.Detto questo, l'OOP è solo uno degli strumenti nella cassetta degli attrezzi delle metodologie di programmazione.Non è la metodologia universale.Sembra che si adatti bene alle applicazioni aziendali di grandi dimensioni.

La maggior parte degli sviluppatori che lavorano con linguaggi OOP utilizzano esempi di OOP eseguiti direttamente nei framework e nei tipi che utilizzano quotidianamente, ma semplicemente non ne sono consapevoli.Ecco alcuni esempi molto semplici:ADO.NET, Hibernate/NHibernate, Logging Frameworks, vari tipi di raccolte di linguaggi, lo stack ASP.NET, lo stack JSP ecc...Queste sono tutte cose che fanno molto affidamento sull'OOP nelle loro basi di codice.

Il riutilizzo non dovrebbe essere un obiettivo dell'OOP o di qualsiasi altro paradigma.

Il riutilizzo è un effetto collaterale di una buona progettazione e di un adeguato livello di astrazione.Il codice ottiene il riutilizzo facendo qualcosa di utile, ma non facendo così tanto da renderlo inflessibile.Non importa se il codice è OO o meno: riutilizziamo ciò che funziona e non è banale farlo da soli.Questo è pragmatismo.

L'idea dell'OO come un nuovo modo per arrivare al riutilizzo attraverso l'ereditarietà è fondamentalmente errata.Come hai notato, le violazioni LSP abbondano.Invece, l’OO è propriamente pensato come un metodo per gestire la complessità di un dominio problematico.L’obiettivo è la manutenibilità di un sistema nel tempo.Lo strumento principale per raggiungere questo obiettivo è la separazione dell'interfaccia pubblica da un'implementazione privata.Ciò ci consente di avere regole come "Questo dovrebbe essere modificato solo utilizzando..." applicate dal compilatore, piuttosto che dalla revisione del codice.

L'utilizzo di questo, sono sicuro che sarai d'accordo, ci consente di creare e mantenere sistemi estremamente complessi.C’è molto valore in questo, e non è facile da realizzare in altri paradigmi.

Al limite del religioso, ma direi che stai dipingendo un quadro eccessivamente cupo dello stato della moderna OOP.Direi che in realtà è così ha costi ridotti, reso gestibili progetti software di grandi dimensioni e così via.Ciò non significa che sia stato risolto il problema fondamentale della confusione del software e non significa che lo sviluppatore medio sia un esperto di OOP.Ma la modularizzazione della funzione in componenti-oggetto ha sicuramente ridotto la quantità di spaghetti code disponibili nel mondo.

Mi vengono in mente dozzine di librerie che sono meravigliosamente riutilizzabili e che hanno permesso di risparmiare tempo e denaro che non potranno mai essere calcolati.

Ma nella misura in cui l'OOP è stata una perdita di tempo, direi che è a causa della mancanza di formazione dei programmatori, aggravata dalla ripida curva di apprendimento dell'apprendimento di una mappatura OOP specifica della lingua.Alcune persone "ottengono" l'OOP e altre non lo faranno mai.

Penso che l'uso di oggetti di contesto opachi (HANDLE in Win32, FILE* in C, per citare due esempi ben noti - diavolo, gli HANDLE vivono dall'altra parte della barriera della modalità kernel, e in realtà non si ottiene molto più incapsulato di così) si trova anche nel codice procedurale;Faccio fatica a capire come questo sia qualcosa di particolare per OOP.

HANDLEs (e il resto della WinAPI) È OPPURE!C non supporta molto bene l'OOP, quindi non esiste una sintassi speciale ma ciò non significa che non utilizzi gli stessi concetti.WinAPI è in ogni senso della parola un framework orientato agli oggetti.

Vedi, questo è il problema con ogni singola discussione che coinvolge l'OOP o tecniche alternative:nessuno ha chiarezza sulla definizione, tutti parlano di qualcos'altro e quindi non è possibile raggiungere un consenso.Mi sembra una perdita di tempo.

È un paradigma di programmazione..Progettato per rendere più semplice per noi comuni mortali scomporre un problema in pezzi più piccoli e realizzabili.

Se non lo trovi utile..Non usarlo, non pagare la formazione e sii felice.

Io invece lo trovo utile, quindi lo farò :)

Rispetto alla programmazione procedurale diretta, il primo principio fondamentale dell'OOP è la nozione di occultamento e incapsulamento delle informazioni.Questa idea porta alla nozione di classe che separa l'interfaccia dall'implementazione.Questi sono concetti estremamente importanti e la base per mettere in atto un quadro per pensare alla progettazione del programma in un modo diverso e migliore (credo).Non puoi davvero discutere contro queste proprietà: non è necessario alcun compromesso ed è sempre un modo più pulito per modulizzare le cose.

Anche altri aspetti dell'OOP, tra cui l'ereditarietà e il polimorfismo, sono importanti, ma come altri hanno accennato, sono comunemente sovrautilizzati.cioè:A volte le persone usano l'ereditarietà e/o il polimorfismo perché possono, non perché dovrebbero.Sono concetti potenti e molto utili, ma devono essere utilizzati con saggezza e non costituiscono vantaggi automatici dell'OOP.

Relativo al riutilizzo.Sono d'accordo che il riutilizzo sia eccessivo per l'OOP.È un possibile effetto collaterale di oggetti ben definiti, tipicamente di classi più primitive/generiche ed è un risultato diretto dei concetti di incapsulamento e di occultamento delle informazioni.È potenzialmente più semplice da riutilizzare perché le interfacce di classi ben definite sono semplicemente più chiare e in qualche modo autodocumentate.

Il problema con l'OOP è che era ipervenduto.

Come lo aveva originariamente concepito Alan Kay, era un'ottima alternativa alla pratica precedente di disporre di dati grezzi e routine globali.

Poi alcuni tipi di consulenti di management si sono attaccati ad esso e lo hanno venduto come il messia del software, e il mondo accademico e l’industria, come dei lemming, sono caduti dietro di lui.

Ora stanno crollando come dei lemming dopo che altre buone idee sono state ipervendute, come la programmazione funzionale.

Quindi cosa farei di diverso?Moltissimo, e ho scritto un libro su questo.(È fuori stampa: non ricevo un centesimo, ma puoi ancora procurartene delle copie.)Amazzonia

La mia risposta costruttiva è considerare la programmazione non come un modo per modellare le cose nel mondo reale, ma come un modo per codificare i requisiti.

Questo è molto diverso e si basa sulla teoria dell’informazione (a un livello che chiunque può comprendere).Dice che la programmazione può essere vista come un processo di definizione dei linguaggi e che l'abilità nel farlo è essenziale per una buona programmazione.

Eleva il concetto di linguaggi specifici del dominio (DSL).Concorda decisamente con DRY (non ripeterti).Dà un grande pollice in su alla generazione del codice.Il risultato è un software con una struttura dati molto inferiore a quella tipica delle applicazioni moderne.

Cerca di rinvigorire l’idea che la via da seguire sta nell’inventiva e che anche le idee ben accettate dovrebbero essere messe in discussione.

HANDLE (e il resto della WinAPI) è OOP!

Lo sono, però?Non sono ereditari, non sono certamente sostituibili, mancano di classi ben definite...Penso che siano molto al di sotto di "OOP".

Hai mai creato una finestra utilizzando WinAPI?Allora dovresti sapere che definisci una classe (RegisterClass), creane un'istanza (CreateWindow), chiamare metodi virtuali (WndProc) e metodi della classe base (DefWindowProc) e così via.WinAPI prende anche la nomenclatura da SmallTalk OOP, chiamando i metodi "messaggi" (Window Messages).

Gli handle potrebbero non essere ereditabili, ma c'è final a Giava.Non mancano di classe, loro Sono un segnaposto per la classe:Questo è il significato della parola "maneggiare".Osservando architetture come MFC o .NET WinForms è immediatamente ovvio che, fatta eccezione per la sintassi, non c'è molto di diverso da WinAPI.

Sì, l'OOP non ha risolto tutti i nostri problemi, mi spiace.Stiamo comunque lavorando su SOA che risolverà tutti questi problemi.

L'OOP si presta bene alla programmazione di strutture interne del computer come i "widget" della GUI, dove ad esempio SelectList e TextBox possono essere sottotipi di Item, che ha metodi comuni come "sposta" e "ridimensiona".

Il problema è che il 90% di noi lavora nel mondo degli affari in cui lavoriamo con concetti aziendali come Fattura, Dipendente, Lavoro, Ordine.Questi non si prestano così bene all'OOP perché gli "oggetti" sono più nebulosi, soggetti a modifiche in base alla reingegnerizzazione aziendale e così via.

Il caso peggiore è quello in cui l'OO viene applicato con entusiasmo ai database, compresi gli eclatanti "miglioramenti" dell'OO ai database SQL, che vengono giustamente ignorati tranne che dai principianti dei database che presumono che debbano essere il modo giusto di fare le cose perché sono più recenti.

Nella mia esperienza di revisione del codice e di progettazione dei progetti che ho svolto, il valore dell'OOP non è stato pienamente realizzato perché molti sviluppatori hanno non ha concettualizzato adeguatamente il modello orientato agli oggetti nelle loro menti.Pertanto non programmano con la progettazione OO, molto spesso continuano a scrivere codice procedurale dall'alto verso il basso rendendo le classi carine Piatto progetto.(se si può anche chiamarlo "design" in primo luogo)

È piuttosto spaventoso osservare quanto poco i colleghi sappiano cosa siano una classe o un'interfaccia astratta, per non parlare della progettazione corretta di una gerarchia di ereditarietà per soddisfare le esigenze aziendali.

Tuttavia, quando è presente un buon design OO, è pura gioia leggere il codice e vedere il codice inserirsi naturalmente in componenti/classi intuitivi.Ho sempre percepito l'architettura e il design del sistema come la progettazione dei vari dipartimenti e delle mansioni del personale in un'azienda: tutti sono lì per realizzare un determinato lavoro nel grande schema delle cose, generando la sinergia necessaria per far avanzare l'organizzazione/sistema.

Questo, ovviamente, è abbastanza raro Purtroppo.Come per il rapporto tra oggetti fisici ben progettati e oggetti orribilmente progettati nel mondo, lo stesso si può dire più o meno dell’ingegneria e del design del software.Avere a disposizione buoni strumenti non garantisce necessariamente buone pratiche e buoni risultati.

Forse un cofano, un grembo o un albero non sono una sedia, ma sono tutti ISittable.

Penso che quelle cose del mondo reale siano oggetti

Fate?

Quali modalità ha la fattura?Oh, aspetta.Non può pagarsi da solo, non può spedirsi, non può confrontarsi con gli articoli che il venditore ha effettivamente consegnato.Non ha alcun metodo;è totalmente inerte e non funzionale.È un tipo di record (una struttura, se preferisci), non un oggetto.

Allo stesso modo le altre cose che menzioni.

Solo perché qualcosa è reale non lo rende un oggetto nel senso OO del termine.Gli oggetti OO sono un peculiare accoppiamento di stato e comportamento che può agire di propria iniziativa.Questo non è qualcosa che è abbondante nel mondo reale.

Ho scritto codice OO negli ultimi 9 anni circa.Oltre all'utilizzo della messaggistica, è difficile per me immaginare un altro approccio.Il vantaggio principale che vedo è totalmente in linea con quanto affermato da CodingTheWheel:modularizzazione.OO mi porta naturalmente a costruire le mie applicazioni da componenti modulari che hanno interfacce pulite e responsabilità chiare (ad es.codice poco accoppiato, altamente coeso con una chiara separazione delle preoccupazioni).

Penso che il punto in cui l’OO crolla è quando le persone creano gerarchie di classi profondamente annidate.Ciò può portare a complessità.Tuttavia, considerare la finzionalità comune in una classe base, quindi riutilizzarla in altre classi discendenti è una cosa profondamente elegante, IMHO!

In primo luogo, le osservazioni sono un po’ approssimative.Non dispongo di dati sulla produttività del software e non ho buone ragioni per credere che non aumenterà.Inoltre, poiché ci sono molte persone che abusano di OO, un buon utilizzo dell’OO non causerebbe necessariamente un miglioramento della produttività, anche se l’OO fosse la cosa più grande dopo il burro di arachidi.Dopotutto, un neurochirurgo incompetente è probabilmente peggio di niente, ma uno competente può avere un valore inestimabile.

Detto questo, l'OO è un modo diverso di organizzare le cose, allegando il codice procedurale ai dati invece di far operare il codice procedurale sui dati.Questo dovrebbe essere almeno una piccola vittoria di per sé, poiché ci sono casi in cui l'approccio OO è più naturale.Dopotutto, non c'è nulla che impedisca a qualcuno di scrivere un'API procedurale in C++, quindi l'opzione di fornire oggetti rende invece il linguaggio più versatile.

Inoltre, c'è qualcosa che OO fa molto bene:consente al vecchio codice di chiamare automaticamente il nuovo codice, senza modifiche.Se ho un codice che gestisce le cose in modo procedurale e aggiungo un nuovo tipo di cose che è simile ma non identico a quello precedente, devo cambiare il codice procedurale.In un sistema OO, eredito la funzionalità, cambio ciò che mi piace e il nuovo codice viene utilizzato automaticamente a causa del polimorfismo.Ciò aumenta la portata dei cambiamenti, e questa è una buona cosa.

Lo svantaggio è che un buon OO non è gratuito:richiede tempo e impegno per impararlo correttamente.Dato che è una parola d'ordine importante, ci sono molte persone e prodotti che lo fanno male, solo per il gusto di farlo.Non è più facile progettare una buona interfaccia di classe che una buona API procedurale, e ci sono tutti i tipi di errori facili da commettere (come le gerarchie di classi profonde).

Consideralo come un tipo diverso di strumento, non necessariamente generalmente migliore.Un martello oltre a un cacciavite, diciamo.Forse alla fine usciremo dalla pratica dell’ingegneria del software sapendo quale chiave usare per avvitare la vite.

@Sean

Tuttavia, considerare la finzionalità comune in una classe base, quindi riutilizzarla in altre classi discendenti è una cosa profondamente elegante, IMHO!

Ma gli sviluppatori "procedurali" lo fanno comunque da decenni.La sintassi e la terminologia potrebbero differire, ma l'effetto è identico.C'è di più nell'OOP che "riutilizzare funzionalità comuni in una classe base", e potrei anche arrivare a dire che è difficile descriverlo come OOP;richiamare la stessa funzione da differenti parti di codice è una tecnica vecchia quanto la stessa sottoprocedura.

@Konrad

L'OOP può essere difettoso e certamente non è una soluzione miracolosa, ma rende le applicazioni su larga scala molto più semplici perché è un ottimo modo per ridurre le dipendenze

Questo è il dogma.Non vedo cosa renda l'OOP significativamente migliore in questo senso rispetto alla vecchia programmazione procedurale.Ogni volta che eseguo una chiamata di procedura mi isolo dalle specifiche dell'implementazione.

Per me, c'è molto valore nella stessa sintassi OOP.Usare oggetti che tentano di rappresentare cose reali o strutture dati è spesso molto più utile che provare a usare un insieme di diverse funzioni flat (o "fluttuanti") per fare la stessa cosa con gli stessi dati.Esiste un certo "flusso" naturale verso le cose con una buona OOP che ha più senso leggere, scrivere e mantenere a lungo termine.

Non ha necessariamente importanza che una fattura non sia realmente un "oggetto" con funzioni che può eseguire da sola: l'istanza dell'oggetto può esistere solo per eseguire funzioni sui dati senza dover sapere che tipo di dati sono effettivamente presenti.La funzione "invoice.toJson()" può essere chiamata con successo senza dover sapere che tipo di dati è "invoice": il risultato sarà Json, non importa se proviene da un database, XML, CSV o anche da un altro oggetto JSON .Con le funzioni procedurali, all'improvviso devi sapere di più sui tuoi dati e ti ritrovi con funzioni come "xmlToJson()", "csvToJson()", "dbToJson()", ecc.Alla fine diventa un disastro completo e un ENORME mal di testa se cambi il tipo di dati sottostante.

Lo scopo dell'OOP è nascondere l'effettiva implementazione astraendola.Per raggiungere questo obiettivo, è necessario creare un'interfaccia pubblica.Per semplificare il tuo lavoro durante la creazione di quell'interfaccia pubblica e mantenere le cose ASCIUTTE, devi utilizzare concetti come classi astratte, ereditarietà, polimorfismo e modelli di progettazione.

Quindi, per me, il vero obiettivo principale dell'OOP è rendere più semplice la manutenzione e le modifiche future del codice.Ma oltre a ciò, può davvero semplificare molto le cose se fatto correttamente in modi che il codice procedurale non potrebbe mai fare.Non importa se non corrisponde al "mondo reale": la programmazione con il codice non interagisce comunque con gli oggetti del mondo reale.L'OOP è semplicemente uno strumento che rende il mio lavoro più semplice e veloce: lo farò ogni giorno.

@CodingTheWheel

Ma nella misura in cui l'OOP è stata una perdita di tempo, direi che è a causa della mancanza di formazione dei programmatori, aggravata dalla ripida curva di apprendimento dell'apprendimento di una mappatura OOP specifica della lingua.Alcune persone "ottengono" l'OOP e altre non lo faranno mai.

Non so se sia davvero sorprendente, però.Penso che gli approcci tecnicamente validi (LSP è la cosa ovvia) facciano difficile da usare, ma se non utilizziamo tali approcci il codice diventa comunque fragile e inestensibile (perché non possiamo più ragionarci su).E penso che i risultati controintuitivi a cui ci porta l'OOP non sorprendano che le persone non se ne accorgano.

Ancora più significativo, dal momento che il software è già fondamentalmente troppo difficile da scrivere in modo affidabile e accurato per gli esseri umani normali, dovremmo davvero esaltare una tecnica che viene costantemente insegnata male e sembra difficile da imparare?Se i benefici fossero evidenti, forse varrebbe la pena perseverare nonostante le difficoltà, ma non sembra essere così.

@Jeff

Rispetto alla programmazione procedurale diretta, il primo principio fondamentale dell'OOP è la nozione di occultamento e incapsulamento delle informazioni.Questa idea porta alla nozione di classe che separa l'interfaccia dall'implementazione.

Quale ha l'implementazione più nascosta:Iostream di C++ o FILE* di C?

Penso che l'uso di oggetti di contesto opachi (HANDLE in Win32, FILE* in C, per citare due esempi ben noti - diavolo, gli HANDLE vivono dall'altra parte della barriera della modalità kernel, e in realtà non si ottiene molto più incapsulato di così) si trova anche nel codice procedurale;Faccio fatica a capire come questo sia qualcosa di particolare per OOP.

Suppongo che potrebbe essere una parte del motivo per cui faccio fatica a vedere i vantaggi:le parti ovviamente buone non sono specifiche dell'OOP, mentre le parti specifiche dell'OOP non sono ovviamente buone!(questo non vuol dire che siano necessariamente dannosi, ma piuttosto che non ho visto prove che siano ampiamente applicabili e costantemente vantaggiosi).

Nell'unico blog di sviluppo che ho letto, da quel ragazzo Joel-On-Software-Founder-of-SO, ho letto molto tempo fa che OO non porta ad aumenti di produttività.La gestione automatica della memoria sì.Freddo.Chi può negare i dati?

Credo ancora che OO stia al non-OO ciò che programmare con le funzioni sta a programmare tutto in linea.

(E dovrei saperlo, dato che ho iniziato con GWBasic.) Quando esegui il refactoring del codice per utilizzare le funzioni, variable2654 diventa variable3 del metodo in cui ti trovi.O, meglio ancora, ha un nome che puoi capire, e se la funzione è breve, è chiamato value e questo è sufficiente per la piena comprensione.

Quando il codice senza funzioni diventa codice con metodi, puoi eliminare chilometri di codice.

Quando esegui il refactoring del codice per renderlo veramente OO, b, c, q, E Z diventare this, this, this E this.E poiché non credo nell'uso del file this parola chiave, puoi eliminare miglia di codice.In realtà, puoi farlo anche se lo usi this.



Non penso che OO sia una metafora naturale.

Non credo nemmeno che il linguaggio sia una metafora naturale, né penso che gli "odori" di Fowler siano migliori del dire "questo codice ha un cattivo sapore". Detto questo, penso che OO non riguardi metafore naturali e persone che pensano che il gli oggetti ti saltano addosso sostanzialmente non capiscono il punto. Tu definisci l'universo degli oggetti, e universi di oggetti migliori danno come risultato un codice più breve, più facile da capire, che funziona meglio o tutti questi (e alcuni criteri che sto dimenticando).Penso che le persone che utilizzano gli oggetti naturali del cliente/dominio come oggetti di programmazione non abbiano il potere di ridefinire l'universo.

Ad esempio, quando crei un sistema di prenotazione aerea, ciò che chiami prenotazione potrebbe non corrispondere affatto a una prenotazione legale/aziendale.



Alcuni dei concetti di base sono strumenti davvero interessanti

Penso che la maggior parte delle persone esageri con quella cosa "quando hai un martello, sono tutti chiodi".Penso che l’altro lato della medaglia/specchio sia altrettanto vero:quando hai un gadget come il polimorfismo/ereditarietà, inizi a trovare usi in cui si adatta come un guanto/calzino/lente a contatto.Gli strumenti di OO sono molto potenti.Penso che l'eredità unica sia assolutamente necessaria affinché le persone non si lascino trasportare, la mia nonostante il software con ereditarietà multipla.



Qual è lo scopo dell'OOP?

Penso che sia un ottimo modo per gestire una base di codice assolutamente enorme.Penso che ti permetta di organizzare e riorganizzare il tuo codice e ti dia un linguaggio per farlo (oltre al linguaggio di programmazione in cui stai lavorando) e modularizza il codice in un modo abbastanza naturale e di facile comprensione.

L'OOP è destinato a essere frainteso dalla maggior parte degli sviluppatori

Questo perché è un processo che apre gli occhi come la vita:capisci l'OO sempre di più con l'esperienza e inizi a evitare determinati schemi e ad impiegarne altri man mano che diventi più saggio.Uno dei migliori esempi è che smetti di usare l'ereditarietà per le classi che non controlli e preferisci il file Facciata modello invece.



Per quanto riguarda il tuo mini-saggio/domanda

Volevo dirti che hai ragione.La riusabilità è per la maggior parte un sogno irrealizzabile.Ecco una citazione di Anders Hejilsberg su questo argomento (brillante) da qui:

Se chiedi ai programmatori principianti di scrivere un controllo calendario, spesso pensano tra se stessi: "Oh, lo farò Scrivi il miglior calendario del mondo controllo!Sarà polimorfico rispetto al tipo di calendario.Avrà espositori e mungers, e questo, quello e l'altro". Essi necessità di spedire un'applicazione di calendario in due mesi.Hanno messo tutto questo l'infrastruttura in atto nel controllo, e poi trascorrere due giorni Scrivere un'applicazione di calendario scadente sopra di esso.Penseranno: "Nel prossima versione dell'applicazione, sono farò molto di più".

Una volta che iniziano a pensare a come stanno effettivamente per implementare tutte queste altre concretizzazioni di il loro design astratto, tuttavia, si scopre che il loro design è completamente sbagliato.E ora l'hanno fatto si sono messi in un angolo, e devono buttare tutto Cambio.L'ho visto più e più volte.Sono un forte sostenitore dell'essere minimalista.A meno che tu non lo sia davvero andando a risolvere il problema generale, Non cercare di mettere in atto un quadro di riferimento per risolverne uno specifico, perché non sai cosa sia quel quadro dovrebbe assomigliare.

Hai mai creato una finestra utilizzando WinAPI?

Più volte di quanto mi interessi ricordare.

Quindi dovresti sapere che definisci una classe (RegisterClass), ne crei un'istanza (CreateWindow), chiami metodi virtuali (WndProc) e metodi della classe base (DefWindowProc) e così via.WinAPI prende anche la nomenclatura da SmallTalk OOP, chiamando i metodi "messaggi" (Window Messages).

Allora saprai anche che non invia messaggi da solo, il che è un grande vuoto.Ha anche una sottoclasse scadente.

Gli handle potrebbero non essere ereditabili, ma in Java c'è il finale.Non mancano di una classe, sono un segnaposto per la classe:Questo è il significato della parola "maneggiare".Osservando architetture come MFC o .NET WinForms è immediatamente ovvio che, fatta eccezione per la sintassi, non c'è molto di diverso da WinAPI.

Non sono ereditabili né nell'interfaccia né nell'implementazione, sono minimamente sostituibili, e non sono sostanzialmente diversi da ciò che i codificatori procedurali fanno da sempre.

È davvero così?Le parti migliori dell'OOP sono semplicemente...codice procedurale tradizionale? Quello è il grosso problema?

Sono completamente d'accordo con InSciTek Jeff's risposta, aggiungerò semplicemente i seguenti perfezionamenti:

  • Nascondere e incapsulare le informazioni:Fondamentale per qualsiasi codice gestibile.Può essere fatto prestando attenzione in qualsiasi linguaggio di programmazione, non richiede funzionalità OO, ma farlo renderà il tuo codice leggermente simile a OO.
  • Eredità:Esiste un importante dominio applicativo per il quale tutti questi OO è una specie di E contiene-a le relazioni sono perfette:Interfacce utente grafiche.Se provi a creare GUI senza il supporto della lingua OO, finirai comunque per creare funzionalità simili a OO ed è più difficile e soggetto a errori senza il supporto della lingua.Glade (recentemente) e X11 Xt (storicamente) per esempio.

L'uso delle funzionalità OO (in particolare le gerarchie astratte profondamente annidate), quando non ha senso, è inutile.Ma per alcuni domini applicativi ha davvero senso.

Credo che la qualità più vantaggiosa dell'OOP sia l'occultamento/gestione dei dati.Tuttavia, ci sono MOLTI esempi in cui l'OOP viene utilizzato in modo improprio e penso che sia qui che entra in gioco la confusione.

Solo perché puoi trasformare qualcosa in un oggetto non significa che dovresti farlo.Tuttavia, se ciò renderà il tuo codice più organizzato/facile da leggere, allora dovresti sicuramente.

Un ottimo esempio pratico in cui l'OOP è molto utile è con una classe "prodotto" e oggetti che utilizzo sul nostro sito web.Poiché ogni pagina è un prodotto e ogni prodotto ha riferimenti ad altri prodotti, può creare molta confusione riguardo a quale prodotto si riferiscono i dati in tuo possesso.Questa variabile "strURL" è il collegamento alla pagina corrente, alla home page o alla pagina delle statistiche?Certo potresti creare tutti i tipi di variabili diverse che fanno riferimento alle stesse informazioni, ma proCurrentPage->strURL è molto più facile da capire (per uno sviluppatore).

Inoltre, allegare funzioni a quelle pagine è molto più pulito.Posso fare proCurrentPage->CleanCache();Seguito da proDisplayItem->RenderPromo();Se chiamassi semplicemente quelle funzioni e presupponessi che i dati attuali fossero disponibili, chissà che tipo di male accadrebbe.Inoltre, se dovessi passare le variabili corrette a quelle funzioni, mi ritroverei al problema di avere in giro tutti i tipi di variabili per i diversi prodotti.

Invece, utilizzando gli oggetti, tutti i dati e le funzioni dei miei prodotti sono belli, puliti e facili da comprendere.

Tuttavia.Il grosso problema con l'OOP è quando qualcuno crede che TUTTO dovrebbe essere OOP.Questo crea molti problemi.Ho 88 tabelle nel mio database.Ho solo circa 6 lezioni e forse dovrei averne circa 10.Sicuramente non ho bisogno di 88 lezioni.Nella maggior parte dei casi l'accesso diretto a tali tabelle è perfettamente comprensibile nelle circostanze in cui lo utilizzo e l'OOP renderebbe effettivamente più difficile/noioso raggiungere la funzionalità principale di ciò che sta accadendo.

Credo che un modello ibrido di oggetti utili e procedurali pratici sia il metodo di codifica più efficace.È un peccato che ci siano tutte queste guerre di religione in cui le persone sostengono l'uso di un metodo a scapito degli altri.Sono entrambi bravi ed entrambi hanno il loro posto.Nella maggior parte dei casi, entrambi i metodi vengono utilizzati in ogni progetto più grande (in alcuni progetti più piccoli, un singolo oggetto o alcune procedure potrebbero essere tutto ciò di cui hai bisogno).

Non mi interessa il riutilizzo tanto quanto la leggibilità.Quest'ultimo significa che il tuo codice è più facile da modificare.Solo questo vale oro nel mestiere di creare software.

E OO è un modo dannatamente efficace per rendere leggibili i tuoi programmi.Riutilizzare o non riutilizzare.

"Il mondo reale non è "OO","

Veramente?Il mio mondo è pieno di oggetti.Ne sto usando uno adesso.Penso che avere "oggetti" software che modellano gli oggetti reali potrebbe non essere una cosa così negativa.

I progetti OO per cose concettuali (come Windows, non le finestre del mondo reale, ma i pannelli di visualizzazione sul monitor del mio computer) spesso lasciano molto a desiderare.Ma per le cose del mondo reale come fatture, ordini di spedizione, richieste di indennizzi assicurativi e quant'altro, penso che quelle cose del mondo reale siano oggetti.Ne ho una pila sulla scrivania, quindi devono essere reali.

Lo scopo dell'OOP è fornire al programmatore un altro mezzo per descrivere e comunicare una soluzione a un problema in codice a macchine e persone.La parte più importante è la comunicazione con le persone.L'OOP consente al programmatore di dichiarare cosa significa nel codice attraverso regole applicate nel linguaggio OO.

Contrariamente a molte argomentazioni su questo argomento, i concetti OOP e OO sono pervasivi in ​​tutto il codice, incluso il codice in linguaggi non OOP come C.Molti programmatori avanzati non OO approssimeranno le caratteristiche degli oggetti anche in linguaggi non OO.

Avere OO integrato nel linguaggio fornisce semplicemente al programmatore un altro mezzo di espressione.

La parte più importante nella scrittura del codice non è la comunicazione con la macchina, quella parte è facile, la parte più importante è la comunicazione con i programmatori umani.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top