Perché è difficile OOP? [chiuso]


92

Quando ho iniziato a utilizzare un linguaggio orientato agli oggetti (Java), praticamente sono diventato "cool" e ho iniziato a scrivere codice. Non ci ho mai pensato fino a poco tempo fa dopo aver letto molte domande su OOP. L'impressione generale che ottengo è che le persone lottano con esso. Dal momento che non l'ho considerato difficile e non direi che sono un genio, sto pensando che avrei dovuto perdere qualcosa o averlo frainteso.

Perché è difficile capire OOP? È difficile da capire?


72
Rispondo: non è difficile da capire, solo difficile da padroneggiare. La programmazione nel suo insieme è così.
Steven Evers,

2
umm, no? Forse i programmatori che non riescono a programmare non riescono a incolpare l'oops invece delle loro righe di codice? non lo so ma non ho mai sentito nessuno dire che è difficile da capire. Comunque ho visto ppl dire che funzionale è strano soprattutto perché non possono cambiare il valore della loro variabile.

5
@ acidzombie42: funzionale non è affatto strano. non è necessario scrivere un elenco di comandi per modificare il contenuto delle variabili che rappresentano una posizione nella RAM. le variabili rappresentano valori, non si modificano i valori; 42 rimane 42, x rimane x - qualunque sia x. scrivi funzioni che mappano dai loro parametri ai risultati. i valori sono: numeri, elenchi di valori, funzioni da valori a valori, programmi che producono effetti collaterali e un valore risultante all'esecuzione e altro. in questo modo, il risultato della funzione principale verrà calcolato dal compilatore, ovvero il programma che può essere eseguito.
comonad

5
Ho imparato Haskell di recente. Più imparo e comprendo sulla programmazione funzionale, più sento che OOP è difficile. Penso che la ragione principale di ciò sia OOP che cerca di collegare i dati (oggetto / classe) insieme alla funzione che li opera (metodo). Questa è la fonte del problema e molti modelli di progettazione OOP sono concepiti per evitare di collegare dati e funzioni. Ad esempio, il modello di fabbrica viene utilizzato per separare il costruttore (che è una funzione) dall'oggetto reale su cui opera.
ming_codes

1
Perché è sbagliato. Dovrebbe davvero essere una programmazione orientata al soggetto, in quanto il soggetto esegue l'azione (verbo) e l'oggetto riceve l'azione: John lancia la palla. Quindi johnsBall.throw () non ha davvero senso.
Chris Cudmore,

Risposte:


120

Personalmente ho trovato la meccanica di OOP abbastanza facile da capire. La parte difficile per me era il "perché" di esso. Quando sono stato esposto per la prima volta, sembrava una soluzione alla ricerca di un problema. Ecco alcuni motivi per cui penso che molte persone lo trovino difficile:

  1. L'IMHO che insegna OO sin dall'inizio è un'idea terribile. La codifica procedurale non è una "cattiva abitudine" ed è lo strumento giusto per alcuni lavori. I metodi individuali in un programma OO tendono comunque ad essere piuttosto procedurali. Inoltre, prima di apprendere la programmazione procedurale abbastanza bene da rendere visibili i suoi limiti, OO non sembra molto utile allo studente.

  2. Prima di poter veramente afferrare OO, è necessario conoscere le basi delle strutture dati e le funzioni di associazione tardiva / ordine superiore. È difficile stimolare il polimorfismo (che in sostanza passa attorno a un puntatore ai dati e a un mucchio di funzioni che operano sui dati) se non capisci nemmeno i concetti di strutturare i dati invece di usare solo le primitive e passare attorno a funzioni di ordine superiore / puntatori a funzioni.

  3. I modelli di progettazione dovrebbero essere insegnati come qualcosa di fondamentale per OO, non come qualcosa di più avanzato. I modelli di progettazione ti aiutano a vedere la foresta attraverso gli alberi e forniscono esempi relativamente concreti di dove OO può semplificare problemi reali e vorrai impararli alla fine comunque. Inoltre, una volta ottenuto OO, la maggior parte dei modelli di progettazione diventa evidente con il senno di poi.


5
risposta favolosa, in particolare il numero 1. Naturalmente i metodi in OO sembrano metodi in un linguaggio procedurale, ma ora sono alloggiati in oggetti che hanno anche uno stato.
Dan Rosenstark,

3
Mi piacciono particolarmente i tuoi punti 1 ° e 3 °. Il mio amico è gaga per i modelli di design e continuo a dirgli che se usi semplicemente il buon OOP, molti di loro derivano in modo molto naturale dal problema iniziale.
CodexArcanum,

7
+1 per "La parte difficile per me è stato il" perché "di esso". Ci vuole un po 'di tempo e fatica per comprendere e applicare le basi del linguaggio (incapsulamento), i principi di progettazione e i metodi di refactoring, verso soluzioni comuni (modelli di progettazione).
Belun,

12
Sono d'accordo con il n. 1, con l'avvertenza che è necessario fare un lavoro migliore per spiegare OO a persone che già sanno programmare in modo procedurale rispetto a quanto è stato fatto quando stavo imparando. No, non è utile o informativo parlare di una Catclasse da cui eredita Mammal, usare un esempio reale da un programma reale che avremmo scritto in modo procedurale. Come una semplice struttura di dati.
Carson63000,

4
-1 I modelli di progettazione sono oggi troppo enfatizzati. Sono importanti, certo, ma: in primo luogo, sono importanti per tutti i paradigmi: funzionali, strutturati, così come OO; e in secondo luogo, non fanno parte del paradigma, solo un comodo componente aggiuntivo che è possibile utilizzare, come molti altri. @SoftwareRockstar lo spiega bene nella sua risposta.
CesarGon,

56

Penso che ci siano alcuni fattori che non sono ancora stati menzionati.

Prima di tutto, almeno in "OOP puro" (ad esempio Smalltalk) in cui tutto è un oggetto, devi distorcere la tua mente in una configurazione piuttosto innaturale per pensare a un numero (per un solo esempio) come un oggetto intelligente anziché solo un valore - poiché in realtà, 21(ad esempio) è davvero solo un valore. Ciò diventa particolarmente problematico quando da un lato ti viene detto che un grande vantaggio di OOP è modellare la realtà più da vicino, ma inizi prendendo ciò che assomiglia moltissimo a una visione ispirata all'LSD anche delle parti più elementari e ovvie di realtà.

In secondo luogo, l'ereditarietà in OOP non segue da vicino neanche i modelli mentali della maggior parte delle persone. Per la maggior parte delle persone, classificare le cose in modo più specifico non ha nulla vicino alle regole assolute necessarie per creare una gerarchia di classi che funzioni. In particolare, creare un oggetto class Dche eredita da un altro class Bsignifica che gli oggetti di class Dcondivisione condividono assolutamente, positivamente tutte le caratteristiche di class B. class Dpuò aggiungere nuove e diverse caratteristiche proprie, ma tutte le caratteristiche di class Bdevono rimanere intatte.

Al contrario, quando le persone classificano le cose mentalmente, in genere seguono un modello molto più flessibile. Ad esempio, se una persona stabilisce alcune regole su ciò che costituisce una classe di oggetti, è abbastanza tipico che quasi ogni regola possa essere infranta fintanto che ne seguono abbastanza altre. Anche le poche regole che non si possono veramente infrangere possono quasi sempre essere "allungate" un po 'comunque.

Solo per esempio, considera "auto" come una classe. È abbastanza facile vedere che la stragrande maggioranza di ciò che la maggior parte della gente pensa come "auto" ha quattro ruote. La maggior parte delle persone, tuttavia, ha visto (almeno una foto di) un'auto con solo tre ruote. Alcuni di noi dell'età giusta ricordano anche una o due macchine da corsa dei primi anni '80 (circa) con sei ruote - e così via. Questo ci lascia sostanzialmente con tre scelte:

  1. Non affermare nulla su quante ruote ha un'auto, ma questo tende a dare per scontato che sarà sempre 4 e che il codice probabilmente si romperà per un altro numero.
  2. Afferma che tutte le auto hanno quattro ruote e classifica quelle altre come "non auto", anche se sappiamo che lo sono davvero.
  3. Progetta la classe per consentire la variazione del numero di ruote, per ogni evenienza, anche se ci sono buone possibilità che questa capacità non sarà mai necessaria, utilizzata o testata correttamente.

L'insegnamento di OOP si concentra spesso sulla costruzione di enormi tassonomie - ad esempio, frammenti di quella che sarebbe una gigantesca gerarchia di tutta la vita conosciuta sulla terra, o qualcosa in quell'ordine. Ciò solleva due problemi: in primo luogo, tende a condurre molte persone a concentrarsi su enormi quantità di informazioni che sono assolutamente irrilevanti per la domanda in corso. A un certo punto ho visto una discussione piuttosto lunga su come modellare le razze di cani e se (per esempio) "barboncino in miniatura" debba ereditare da "barboncino a grandezza naturale", o viceversa, o se ci dovrebbe essere una base astratta "Barboncino "classe, con" barboncino a grandezza naturale "e" barboncino in miniatura "che ereditano entrambi. Ciò che tutti sembravano ignorare era che l'applicazione doveva occuparsi di tenere traccia delle licenze per cani,

In secondo luogo, e quasi importante, porta a concentrarsi sulle caratteristiche degli articoli, invece di concentrarsi sulle caratteristiche che sono importanti per il compito da svolgere. Porta a modellare le cose così come sono, dove (la maggior parte delle volte) ciò che è veramente necessario è costruire il modello più semplice che soddisferà le nostre esigenze e usare l'astrazione per adattarsi al necessario sottoclassi per adattarsi all'astrazione che abbiamo costruito.

Infine, ripeto: stiamo lentamente seguendo lo stesso percorso intrapreso dai database nel corso degli anni. I primi database seguivano il modello gerarchico. Oltre a concentrarsi esclusivamente sui dati, questa è una singola eredità. Per un breve periodo, alcuni database hanno seguito il modello di rete, sostanzialmente identico all'ereditarietà multipla (e visti da questo punto di vista, interfacce multiple non sono abbastanza diverse dalle classi di base multiple da notare o preoccuparsi).

Molto tempo fa, tuttavia, i database convergevano in gran parte sul modello relazionale (e anche se non sono SQL, a questo livello di astrazione anche i database "NoSQL" attuali sono relazionali). I vantaggi del modello relazionale sono sufficientemente noti che non mi preoccuperò di ripeterli qui. Noterò solo che l'analogo più vicino al modello relazionale che abbiamo nella programmazione è la programmazione generica (e scusate, ma nonostante il nome, i generici Java, per esempio, non si qualificano davvero, sebbene siano un piccolo passo nel giusta direzione).


Molto ben affermato, e soprattutto che la maggior parte dei problemi con OOP che offri non sono solo problemi con la comprensione dei principianti, ma piuttosto problemi di OOP in generale che la maggior parte dei programmatori di OOP impara a pensare. Recentemente ho lavorato con la progettazione di giochi in cui un modello di componente funziona molto bene, il che si avvicina strettamente alla nozione di modelli relazionali piuttosto che gerarchici.
CodexArcanum,

7
Heh, stavo solo pensando a questo l'altro giorno. Come tutto il primo materiale di apprendimento che ho letto su OOP sembrava focalizzarsi sull'eredità, mentre la mia esperienza sempre più mi dice che l'eredità è per lo più inutile se non dannosa.
rmac,

Sembra una programmazione orientata alle tabelle , anche se dirò che realizzerò di più che OOP non è il proiettile d'argento dello sviluppo del software.
Onesimus Nessun impegno

1
@OnesimusUnbound: la differenza è che la programmazione generica è un modo reale e pratico per fare qualcosa, mentre la programmazione orientata al tavolo è per lo più una delirio folle su una teoria su come qualcosa potrebbe funzionare (leggi i vecchi post di TopMind in comp.object, e tu Capirò cosa intendo - in realtà, i post potrebbero non essere tutti vecchi; per quanto ne so, continua ancora oggi).
Jerry Coffin,

3
Ecco perché le interfacce sono così fantastiche. Prendi la modellazione dell'eredità e la inverti in un primo approccio. Ad esempio, con l'esempio del cane si può presumere che ogni cane abbia un genere e fino a due super specie (una per ciascun genitore) per una razza particolare. Potrebbe esserci anche una proprietà elenco contenente tratti, ma la possibile varietà rende inutile inserirli in una struttura definita. È meglio implementare una ricerca approfondita per gattonare i tratti e combinare razze simili sulla base di tali risultati.
Evan Plaice,

26

OOP richiede la capacità di pensare in modo astratto; un dono / maledizione che poche persone, anche programmatori professionisti, hanno davvero.


35
Tutta la programmazione è astratta.
JeffO,

28
@Jeff O - Non sono d'accordo. La programmazione richiede solo la capacità di dire a qualcuno come fare qualcosa in modo graduale. Se riesci a dire a qualcuno come preparare un sandwich con burro di arachidi e gelatina, hai la possibilità di digitare i comandi in un'interfaccia di programmazione. Questa è una serie di abilità completamente diversa dalla modellazione astratta di ap, b & j sandwich e da come interagisce con il mondo.
John Kraft,

16
Consegnare a qualcuno 2 matite e poi passandole 1 matita e chiedendo quante matite hanno, è concreto. 2 + 1 = 3 è astratto.
JeffO,

17
Sono d'accordo con Jeff. La programmazione fondamentalmente sta gestendo le astrazioni. Almeno questo è vero per tutto tranne che per il flusso di programma più elementare (perché tutto il resto sarà troppo complesso senza astrazioni). C'è una fase distinta nell'apprendimento del programma quando il principiante impara a controllare le astrazioni. Ecco dove cade la metafora della ricetta. La programmazione non è come cucinare e mentre un singolo algoritmo può essere paragonato a una ricetta, la programmazione è fondamentalmente diversa dall'implementazione di algoritmi isolati.
Konrad Rudolph,

2
@KonradRudolph Ottimo punto. +1 per "Tutto il resto sarà troppo complesso senza astrazioni" .
Karthik Sreenivasan,

21

Penso che puoi riassumere la difficoltà di base in questo modo:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Certo, le persone possono abituarsi alla mappatura di "sinistra" come 270, e sì, dire "Car.Turn" invece di "girare la macchina" non è un grande salto. MA, per gestire bene questi oggetti e crearli, devi invertire il modo in cui pensi normalmente.

Invece di manipolare un oggetto, stiamo dicendo all'oggetto di fare effettivamente le cose da solo. Potrebbe non sembrare più difficile, ma dire a una finestra di aprirsi sembra strano. Le persone che non sono abituate a questo modo di pensare devono lottare con quella stranezza ancora e ancora fino a quando alla fine diventa in qualche modo naturale.


7
Buona visione. Penso che il problema sia che nella vita reale non c'è molto che un "oggetto" possa fare che non sia relativo ad altri oggetti. OO funziona bene fino a quando viene detto agli oggetti di modificare il loro stato interno: rectangle.enlarge (margin_in_pixels) ma ho realizzato i limiti anni fa. Un giorno noi programmatori stavamo installando l'hardware. Qualcuno ha scherzato "screw.turn" Divertente, ma mi ha fatto pensare: certo, una vite può cambiarne l'orientamento, ma è davvero un'operazione tra cabinet e vite; nessuno degli oggetti può svolgere il compito da solo. OO non è abbastanza buono.
DarenW,

3
+1, dopo anni di scrittura "substr (data, 0,4)", è difficile scrivere "date.substring (0,4)"
ern0

4
+1 per lo snippet di codice. Descrive chiaramente un processo di pensiero reale.
Karthik Sreenivasan,

2
In realtà lo leggerei come un comando che invii. Come in "dì alla macchina di girare a sinistra". Oop si basava sull'invio di messaggi agli oggetti, quindi è così che lo interpreterei.
bunglestink il

1
Buona intuizione, quindi forse OOP è più adatto per modellare "sistemi di agenti"?
Qbik

21

Ogni paradigma richiede una certa spinta "oltre il limite" per afferrare, per la maggior parte delle persone. Per definizione, è una nuova modalità di pensiero e quindi richiede una certa quantità di lasciar andare le vecchie nozioni e una certa quantità di comprendere appieno perché le nuove nozioni sono utili.

Penso che gran parte del problema sia che i metodi usati per insegnare la programmazione informatica sono piuttosto scarsi in generale. OOP è così comune ora che non è così evidente, ma lo vedi ancora spesso nella programmazione funzionale:

  • concetti importanti sono nascosti dietro nomi strani (FP: Cos'è una monade? OOP: Perché li chiamano funzioni a volte e metodi altre volte?)

  • strani concetti sono spiegati in metafora anziché in termini di ciò che effettivamente fanno, o perché li useresti, o perché qualcuno abbia mai pensato di usarli (FP: Una monade è una tuta spaziale, racchiude un po 'di codice. OOP: An l'oggetto è come un'anatra, può fare rumore, camminare ed ereditare dall'animale)

  • le cose buone variano da persona a persona, quindi non è del tutto chiaro quale sarà il punto di svolta per qualsiasi studente, e spesso l'insegnante non riesce nemmeno a ricordare. (FP: Oh, le monadi ti permettono di nascondere qualcosa nel tipo stesso e portarlo avanti senza dover scrivere esplicitamente ciò che sta accadendo ogni volta. OOP: Oh, gli oggetti ti consentono di mantenere le funzioni per un tipo di dati con quei dati.)

La cosa peggiore è che, come indica la domanda, alcune persone si affretteranno immediatamente a capire perché il concetto è buono e altri no. Dipende davvero da quale sia il punto critico. Per me, capire che gli oggetti archiviano dati e metodi per tali dati è stata la chiave, dopo che tutto il resto si adattava semplicemente come estensione naturale. Poi ho fatto salti successivi come rendermi conto che una chiamata di metodo da un oggetto è molto simile a quella di effettuare una chiamata statica con quell'oggetto come primo parametro.

I piccoli salti successivi aiutano a perfezionare la comprensione, ma è quello iniziale che prende una persona da "OOP non ha senso, perché le persone fanno questo?" a "OOP è il migliore, perché le persone fanno qualcos'altro?"


8
In particolare odio il metaforismo, il più delle volte confondono piuttosto che descriverlo.
Lie Ryan,

3
"Poi ho fatto salti successivi come rendermi conto che una chiamata di metodo da un oggetto è molto simile a quella di effettuare una chiamata statica con quell'oggetto come primo parametro." Vorrei che questo fosse enfatizzato maggiormente fin dall'inizio, come in lingue come Python.
Jared Updike,

1
Il mio problema con l'uso delle metafore per spiegare i concetti è che l'insegnante si ferma spesso alla metafora, come se ciò spiegasse l'intera cosa. No, questa non è una spiegazione completa; questa è solo un'illustrazione per aiutarci a avvolgere la testa attorno alla spiegazione reale .
jhocking

Bella risposta! +1 per spiegare che il primo passo per comprendere OOP sarà più significativo di quello che verrà dopo come estensioni naturali con una buona comprensione delle fondamenta. : D
Karthik Sreenivasan,

dittos sull'apprendimento "balzato": quando ho iniziato a percepire OOP come "semplicemente" costruzione modulare / strutturata / saggia, ma con steroidi; quando ho riscritto alcuni programmi COBOL molto vecchi e maledetti. Nonostante l'ambito globale di COBOL, avevo essenzialmente applicato i principi OO con strutture di record personalizzate, variabili monouso e paragrafi (metodi) strettamente focalizzati, modulari e strutturati.
radarbob,

15

Perché la spiegazione di base di OOP ha molto, molto poco a che fare con il modo in cui viene utilizzato sul campo. La maggior parte dei programmi per insegnarla tenta di utilizzare un modello fisico, come "Pensa a un'auto come un oggetto, e le ruote come oggetti, e le porte e la trasmissione ...", ma al di fuori di alcuni casi oscuri di programmazione di simulazione, gli oggetti sono molto più spesso usati per rappresentare concetti non fisici o per introdurre il riferimento indiretto. L'effetto è che fa capire alle persone in modo intuitivo nel modo sbagliato.

Insegnare dai modelli di progettazione è un modo molto migliore per descrivere OOP, in quanto mostra ai programmatori come alcuni problemi di modellazione reali possono essere effettivamente attaccati con oggetti, piuttosto che descriverli in astratto.


13

Non sono d'accordo con la risposta di dsimcha per la maggior parte:

  1. Insegnare OO sin dall'inizio non è in realtà una cattiva idea in sé, né insegnare linguaggi procedurali. L'importante è insegnare alle persone a scrivere un codice chiaro, conciso e coerente, indipendentemente da OO o procedurale.

  2. I metodi individuali nei buoni programmi OO NON tendono a essere affatto procedurali. Questo sta diventando sempre più vero con l'evoluzione dei linguaggi OO (leggi C # perché a parte C ++ è l'unico altro linguaggio OO che conosco) e la loro sintassi che diventa sempre più complessa di giorno in giorno (lambda, LINQ agli oggetti, ecc.). L'unica somiglianza tra i metodi e le procedure OO nei linguaggi procedurali è la natura lineare di ciascuno, che dubito cambierebbe presto.

  3. Non è possibile padroneggiare un linguaggio procedurale senza comprendere le strutture dei dati. Il concetto di puntatore è importante tanto per i linguaggi procedurali quanto per i linguaggi OO. Passare i parametri per riferimento, ad esempio, che è abbastanza comune nei linguaggi procedurali, richiede di comprendere i puntatori tanto quanto è necessario per imparare qualsiasi linguaggio OO.

  4. Non penso che i modelli di progettazione debbano essere insegnati nelle prime fasi della programmazione OO, perché non sono affatto fondamentali per la programmazione OO. Si può sicuramente essere un buon programmatore OO senza sapere nulla sui modelli di progettazione. In effetti una persona può persino usare modelli di design noti senza nemmeno sapere che sono documentati come tali con nomi propri e che i libri sono scritti su di essi. Ciò che dovrebbe essere insegnato fondamentalmente sono i principi di progettazione come Responsabilità singola, Open Close e Interface Segregation. Sfortunatamente, molte persone che al giorno d'oggi si considerano programmatori OO non hanno familiarità con questo concetto fondamentale o semplicemente scelgono di ignorarlo ed è per questo che abbiamo così tanto codice OO spazzatura là fuori.

Per rispondere alla domanda del poster originale, sì, OO è un concetto più difficile da comprendere rispetto alla programmazione procedurale. Questo perché non pensiamo in termini di proprietà e metodi degli oggetti della vita reale. Ad esempio, il cervello umano non pensa prontamente a "TurnOn" come un metodo TV, ma lo vede come una funzione dell'accensione umana della TV. Allo stesso modo, il polimorfismo è un concetto estraneo a un cervello umano che generalmente vede ogni oggetto della vita reale con una sola "faccia". L'eredità di nuovo non è naturale per il nostro cervello. Solo perché sono uno sviluppatore non significa che mio figlio sarebbe uno. In generale, il cervello umano deve essere addestrato per imparare OO mentre i linguaggi procedurali sono più naturali.


2
+1 - Anche io non penso che i modelli di progettazione siano necessari per l'insegnamento di OOP a livello fondamentale, puoi essere un buon programmatore di OOP e non conoscere alcun modello di progettazione. D'altro canto, si tende a vedere modelli di design noti emergere naturalmente da buoni programmatori OOP. I modelli di progettazione vengono sempre scoperti, non inventati.
Gary Willoughby,

1
+1 - Ottima risposta. Mi piace il quarto punto che hai affermato. È vero che si può essere un buon programmatore OO senza sapere cosa sono veramente gli schemi di design!
Karthik Sreenivasan,

Sono d'accordo con il n. 4 perché la maggior parte dei modelli di progettazione non sono altro che un approccio bubblegum / nastro adesivo per codificare espressamente i limiti del linguaggio. In altri paradigmi i modelli di progettazione possono essere completamente diversi e basati sui propri vincoli. Non sono d'accordo con 2, LINQ e lambda sono ancora eseguiti in modo procedurale e forniscono solo astrazioni di livello superiore ben confezionate. Dedica un po 'di tempo allo sviluppo con un linguaggio procedurale / funzionale tipicamente dinamico come JavaScript e vedrai cosa intendo.
Evan Plaice

6

Penso che molti programmatori abbiano difficoltà a progettare e pianificare in anticipo. Anche se qualcuno fa tutto il design per te, è ancora possibile staccarsi dai principi OOP. Se prendo un sacco di spaghetti code e lo scarico in una classe, è davvero OOP? Qualcuno che non capisce OOP può ancora programmare in Java. Inoltre, non confondere la difficoltà di comprensione con la volontà di non seguire una determinata metodologia o di non essere d'accordo con essa.


5

Dovresti leggere Oggetti Mai? Bene, quasi mai. (Iscrizione ACM richiesta) da Mordechai Ben-Ari che suggerisce che OOP è così difficile, perché non è un paradigma che è in realtà naturale per modellare qualcosa. (Anche se ho delle riserve sull'articolo, perché non è chiaro quali criteri ritiene che un programma debba soddisfare per dire che è scritto sul paradigma OOP in contrapposizione a un paradigma procedurale che utilizza un linguaggio OO.)


5

La programmazione orientata agli oggetti in sé non è difficile.

La parte difficile arriva nel farlo bene. Dove mettere il taglio tra il codice in modo da poter spostare facilmente le cose sull'oggetto base comune ed estenderle in seguito? Come rendere il tuo codice utilizzabile da altri (estendi le classi, includi i proxy, ignora il metodo) senza saltare attraverso i cerchi per farlo.

Questa è la parte difficile, e se fatto bene può essere molto elegante, e se fatto male può essere molto goffo. La mia esperienza personale è che richiede molta pratica per essere stato in tutte le situazioni in cui VORREI averlo fatto diversamente, per farlo abbastanza bene questa volta.


"La mia esperienza personale è che richiede molta pratica in tutte le situazioni in cui VORREI che tu l'abbia fatto in modo diverso, per farlo abbastanza bene questa volta." OOP sembra un elenco codificato di modi per non sbagliare, il che non ha senso fino a quando non lo hai fatto in tutti i modi.
Jared Updike,

@Jared, non del tutto. Confrontalo con la risoluzione di sodukus. Ci sono vari trucchi che puoi fare per risolverlo, ma ci vuole tempo e pratica per farlo bene senza tornare indietro.

Se si pensa a un "oggetto base comune" come un antenato comune, allora diventa chiaro. È davvero così semplice. È difficile capire b / c ci sono così tante spiegazioni fuorvianti là fuori da persone che cercano di apparire intelligenti.
annoying_squid

4

Stavo solo guardando un video di Richard Feynman che parla di come le persone potrebbero effettivamente avere metodologie completamente diverse in testa quando pensano - intendo completamente diverse.

Quando eseguo progetti di alto livello, visualizzo gli oggetti, posso vederli, vedere le loro interfacce e vedere quali percorsi le informazioni devono percorrere.

Ho anche difficoltà a ricordare i dettagli e ho riscontrato che OO è un grande aiuto organizzativo, molto più facile da trovare funzionalità rispetto alla scansione di un elenco di subroutine organizzato in modo non ordinato.

Per me OO è stato un grande vantaggio, ma se non visualizzi allo stesso modo o non esegui un'architettura di alto livello, è probabilmente inutile e fastidioso.


+1 Mi sento allo stesso modo, ma ci sono molte spinte nella direzione opposta, compresi i mixin di Ruby ... che ti fanno capire che l'OO rigoroso non è per tutti.
Dan Rosenstark,

@Yar Yep, è praticamente quello che stavo dicendo. Anche se personalmente non riesco a immaginare niente di meglio (e Ruby mi ha guidato NUTS per l'anno in cui l'ho usato), sto iniziando ad accettare che tutti hanno un modo diverso di vederlo. Forse alcune persone usano il tatto o l'udito quando pensano invece di visualizzare e OO semplicemente non interviene per loro.
Bill K,

Penso che aiuti anche a incoraggiare convenzioni di denominazione più naturali. Non è più necessario codificare il tipo di una funzione nel nome della funzione (come INSTR) - perché il nome è associato al tipo (come string::find)
Ken Bloom,

@Ken anche se sono d'accordo, penso che sia più una questione di digitazione forte di OO - Ruby ha OO ma perdi molte informazioni sul tipo a causa della digitazione di anatra - Ruby tende a dire semplicemente "invia" e si aspetta per sapere quale metodo magico "esso" deve implementare per funzionare.
Bill K,

@Bill, hai ragione. È più una questione di linguaggi che supportano la programmazione generica. Puoi ottenere simpatiche convenzioni di denominazione naturali con i moduli e i sistemi di typeclass come quello di Haskell, e non c'è nulla di OO in Haskell. Se C avesse un sovraccarico, potresti ottenere gli stessi tipi di nomi generici in C.
Ken Bloom il

4

Avevo fatto GW-Basic e Turbo Pascal programmazione di un bel po 'prima di essere introdotto al OO, quindi inizialmente DID fare la mia testa.

Non ho idea se questo è ciò che accade agli altri, ma per me è stato così: il mio processo di pensiero sulla programmazione era puramente procedurale. Come in: "succedono cose del genere, poi succedono cose del genere", ecc. Ecc. Non ho mai considerato le variabili e i dati qualcosa di più che fugaci attori nel flusso del programma. La programmazione era "il flusso di azioni".

Suppongo che ciò che non è stato facile da capire (per quanto stupido sia quello che mi sembra ora), era l'idea che i dati / le variabili contino davvero , in un senso più profondo del semplice essere attori fugaci nel "flusso" del programma. O per dirla in un altro modo: ho continuato a cercare di capirlo attraverso ciò che accade , piuttosto che attraverso ciò che è , che è la vera chiave per afferrarlo.


Punto di vista interessante. Mentre faccio fatica a dare un senso a un massiccio progetto C ++, penso di essere l'opposto, pensando principalmente in termini di dati, il "percorso del segnale" dei bit da qualche "input" a qualche "output". Mentre anch'io ho fatto molto di base e Pascal, il mio primo pensiero tecnico era in elettronica.
DarenW,

3

Non penso che sia difficile da capire, ma può darsi che molte query dei programmatori siano nuove al concetto, provenienti da linguaggi procedurali.

Da quello che ho visto / letto molte persone (almeno nei forum) cercano un 'risultato' da OOP. Se sei un programmatore procedurale che non torna indietro e modifica estende il proprio codice, probabilmente può essere difficile comprenderne i vantaggi.

Inoltre, ci sono molte cattive OOP là fuori, se le persone lo leggono / vedono, allora è facile capire perché potrebbero trovarlo difficile.

IMO devi aspettare fino a quando "scatta" o essere insegnato da qualcuno con una vera conoscenza, non penso che tu possa correre.


5
Se vieni da un ambiente accademico, i tipi di programmi giocattolo che scrivi lì sembrano davvero inutili anche in OOP. Ho iniziato a studiare C al college, ed è stato abbastanza facile da capire perché ogni programma era di 1 pagina, meno di 100 righe. Quindi si tenta di imparare OOP e richiede tutto questo bagaglio e sovraccarico di oggetti solo per fare la stessa cosa, e sembra inutile. Ma fino a quando non hai scritto un programma su molti file e poche migliaia di righe, è difficile capire perché qualsiasi stile di programmazione sia utile.
CodexArcanum,

3

Penso che il motivo per cui OOP sia difficile per molti è perché gli strumenti non lo facilitano davvero.

I linguaggi informatici oggi sono un'astrazione di ciò che sta accadendo nel computer.

OOP è un modo astratto per rappresentare le astrazioni.

Quindi stiamo usando un'astrazione per costruire astrazioni con un'astrazione. Aggiungete a ciò che ciò che stiamo astraggendo di solito sono interazioni fisico / sociali molto complesse e, beh, non c'è da stupirsi.


2

In realtà ho un blog chiamato "Lotte nella programmazione orientata agli oggetti", che è nato da alcune delle mie lotte per impararlo. Penso che sia stato particolarmente difficile da capire perché ho passato così tanto tempo a utilizzare la programmazione procedurale e ho avuto un momento difficile capire come un oggetto potesse essere rappresentato da una raccolta di attributi e comportamenti (ero abituato a semplicemente una raccolta di variabili e metodi).

Inoltre, ci sono molti concetti che orientano un oggetto linguistico - eredità, interfacce, polimorfismo, composizione, ecc. C'è davvero molto da imparare sulla teoria prima che tu possa effettivamente scrivere codice in modo efficace e in un oggetto orientato modo, mentre con la programmazione procedurale, è semplicemente una questione di capire cose come l'allocazione di memoria per le variabili e il punto di ingresso chiama ad altri metodi.


D'accordo: la maggior parte delle difficoltà che le persone hanno con OO è che si sono allenate a pensare "proceduralmente". Non c'è nulla di intrinsecamente difficile in OO ma se "conosci" le tecniche procedurali, sarebbe una sorpresa vedere un altro modo di strutturare le cose.
Kirk Broadhurst,

Senza dubbio è un modo di pensare completamente diverso dalla programmazione procedurale. Ma contrariamente a quanto molti dicono, non è A) un modo di pensare innaturale, e B) complicato. Penso solo che non sia stato insegnato bene.
annoying_squid

2

Motivazione. È più difficile imparare qualcosa quando non vedi il perché, e anche quando non riesci a vedere cosa hai fatto e capire se l'hai fatto bene o no.

Ciò che serve sono piccoli progetti che usano OO per fare cose utili. Suggerirei di sfogliare un libro sui modelli di design e ne troverei uno che è ovviamente utile e funziona bene con OO. (Ho usato la strategia una volta che l'ho provato. Qualcosa come Flyweight o Singleton sarebbe una scelta sbagliata, dal momento che sono modi di usare gli oggetti in generale, non usare gli oggetti per realizzare qualcosa.)


Le persone parlano sempre di Singleton, ma poi è sempre invitato alla festa. Ma è vero, è il non-OO OO DP.
Dan Rosenstark,

-1

Penso che dipenda dall'età (età come proxy dell'esperienza) e, soprattutto, dall'interesse. Se sei "giovane" (cioè, verde, forse) e non hai mai pensato in nessun altro modo, sembra abbastanza semplice. D'altra parte, se pensi che sia la cosa più bella che tu abbia mai visto - mi è successo all'età di 28 anni o qualcosa del genere - è facile brontolare.

D'altra parte, se pensi, come hanno fatto molti dei miei studenti Java, "perché stiamo imparando questo, è solo una moda passeggera", è praticamente impossibile da imparare. Questo è vero con la maggior parte delle tecnologie.


1
OO una moda passeggera? Quanti anni hanno i tuoi studenti - sospetto che questa "mania" sia più antica di loro (il primo OO che ho fatto - che sapevo di aver fatto - era Simula nel 1983/4 e Simula non era nuova a quel punto)
Murph

@Murph Questo avveniva tra il 2004 e il 2005 e gli studenti avevano decisamente più di 45-50 anni (programmatori professionisti all'Iberia).
Dan Rosenstark,

ok, posso vedere come potrebbero aver perso l'inizio della cosa OO. Ma nel 2004/5 ci siamo trovati benissimo in .NET, che è praticamente OO da parete a parete (-: ci sono cose in sviluppo che si potrebbero descrivere come mode, ma quelle che non si agitano rapidamente tendono ad evolversi in cose buone
Murph

1
@Murph, ad essere sinceri, questi ragazzi erano programmatori di mainframe che stavano cercando di convertire in Java. In realtà è stata un'esperienza divertente e unica (non una tariffa normale per i miei giorni di Java Trainer). Si è vero, però, che avevano visto molte cose vanno e vengono, ma ovviamente OO è più di una moda passeggera. In una nota a parte: speravo che questa cosa di Unit Testing sarebbe finita come una mania, ma ora trovo che ho molti test unitari da scrivere ... :)
Dan Rosenstark,

-1

Indipendentemente dal paradigma (OOP, funzionale, ecc.) Che scegli, per scrivere un programma per computer, devi sapere quali passi farà il tuo programma.

Il modo naturale di definire un processo è scrivere i suoi passaggi, per attività più grandi si suddivide l'attività in passaggi più piccoli. Questo è il modo procedurale, questo è il modo in cui funziona il computer, questo è il modo in cui passi attraverso la tua lista di controllo passo dopo passo.

OOP è un modo diverso di pensare. Invece di pensare a una lista di compiti che devono essere fatti passo dopo passo, pensi agli oggetti, alle loro capacità e relazioni. Quindi scriverai molti oggetti, piccoli metodi e il tuo programma funzionerà magicamente. Per raggiungere questo obiettivo, devi cambiare idea ...

Ed è per questo che OOP è difficile. Poiché tutto è un oggetto, tutto ciò che fa è chiedere ad altri oggetti di fare qualcosa, e quegli altri oggetti fondamentalmente fanno alcuni. Quindi il controllo in un programma OOP può saltare selvaggiamente avanti e indietro tra gli oggetti.


-1

Come qualcuno che sta attualmente imparando la programmazione e avendo alcuni problemi in questo settore, non penso che sia così difficile che il concetto sia difficile da capire come lo sono le specifiche implementazioni di tale concetto. Lo dico perché ho avuto l'idea di OOP e l'ho usato in PHP per circa un anno, ma mentre passo a C # e guardo l'uso di oggetti da parte di altri programmatori, trovo che molte persone lo fanno in modi che non capisco. È proprio questo che mi ha portato lungo la strada per trovare una migliore comprensione dei principi di OOP.

Ovviamente, mi rendo conto che il problema è molto probabilmente la mia mancanza di esperienza con un linguaggio nativamente OOP, e che col passare del tempo troverò nuovi modi per utilizzare oggetti che non saranno altrettanto chiari per un nuovo programmatore come quello che sono attualmente in corso. Jerry Coffin lo tocca alcune volte, in particolare nel suo commento:

Ciò diventa particolarmente problematico quando da un lato ti viene detto che un grande vantaggio di OOP è modellare la realtà più da vicino, ma inizi prendendo ciò che assomiglia moltissimo a una visione ispirata all'LSD anche delle parti più elementari e ovvie di realtà.

Trovo che questo sia molto accurato, poiché è l'impressione che ottengo spesso quando vedo qualcuno creare lezioni per cose che non sono realmente cose - un esempio specifico mi sfugge, ma il più vicino che posso trovare al volo è trattare la distanza come un oggetto (lo modificherò la prossima volta che vedrò qualcosa che provoca questa stessa confusione). A volte, OOP sembra trascurare temporaneamente le proprie regole e diventa meno intuitivo. Ciò accade più spesso quando gli oggetti producono oggetti, ereditati da una classe che li incapsula, eccetera.

Penso che per qualcuno come me, sia utile pensare al concetto di oggetti come avere più sfaccettature, una delle quali include il trattamento di qualcosa come un oggetto quando altrimenti non sarebbe. Qualcosa come la distanza, con solo un piccolo cambio di paradigma, potrebbe apparire come un oggetto teorico, ma non uno che potrebbe essere tenuto in mano. Devo pensarlo come se avesse un insieme di proprietà ma un insieme più astratto di comportamenti, come l'accesso alle sue proprietà. Non sono sicuro che questa sia la chiave per la mia comprensione, ma sembra essere dove conducono i miei studi attuali.


1
Una coppia di punti o oggetti dovrebbe essere considerata come un oggetto. E la distanza dovrebbe essere presa in funzione dell'oggetto. L'uso di oggetti non significa che si crea oggetto da tutto.
Gangnus,

Come ho detto, la distanza era un cattivo esempio. Per quanto riguarda la creazione di un oggetto da tutto, mi riferisco specificamente a ciò che ho visto accadere, non a ciò che ho effettivamente fatto - che non è ancora nulla.
dsimer,

Dipende dalla lingua: in SmallTalk la distanza (e tutto il resto) È un oggetto. Ma in C # hai detto che sarebbe male.
Gangnus,

-2

Le terminologie sono state il mio ostacolo quando ho appreso i principi della programmazione orientata agli oggetti (POOP). È quando capisci i fondamenti che i pezzi iniziano a sistemarsi. Proprio come tutto ciò che impara nuovi concetti è un po 'difficile.

Concordato che i modelli di progettazione dovrebbero essere pensati almeno parallelamente a OOP.


-2

Il salto principale per me era solo comprendere il concetto astratto di OOP. Ora sono molto nuovo nella programmazione in generale, sto programmando da un anno a un anno e mezzo, quindi la mia introduzione a OOP è stata con Actionscript ed Processing. Quando ho appreso per la prima volta il codice Actionscript, non era in OOP. Ho imparato a programmare direttamente nel pannello Azioni ed è così che ho imparato i fondamenti di base della programmazione (variabili, funzioni, cicli, ecc.). Così l'ho imparato facendo qualcosa direttamente sul palco in Flash o Processing.

Quando OOP è entrato nelle cose, rendermi conto che potevo creare metodi e proprietà all'interno di un oggetto per poterlo usare e riutilizzare è stato per me un po 'difficile da capire all'inizio. Tutto era molto astratto e difficile da elaborare, ma i linguaggi di programmazione stessi erano molto meglio, ma in un certo senso ci è voluto un balzo di fede per creare quei collegamenti all'inizio.


wow una parte di ciò non aveva alcun senso. "Tutto era molto astratto e difficile da elaborare tra le classi e le istanze di oggetti ecc. Ma una volta ottenuto OOP, i linguaggi di programmazione sono diventati molto più facili da capire. Ma all'inizio è stato necessario fare un salto di qualità"

-2

Ricetta

Buona comprensione di OOP = buon mentore o buoni libri o entrambi + interesse personale + pratica.

Interesse personale

Dalla mia esperienza personale, l'interesse personale arriva a fare molta strada per passare dalla programmazione procedurale a OOP con i giusti input da mentori o buoni libri o entrambi combinati .

Pratica, pratica e pratica

Il mio migliore amico per comprendere meglio OOP non è stato altro che pratica. Ciò favorirà sicuramente le tue abilità OOP.

Come dice il proverbio "Non c'è sostituto del duro lavoro e nessuna scorciatoia per il successo".

In bocca al lupo!

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.