Qual è il punto di OOP?


126

Per quanto ne so, nonostante gli innumerevoli milioni o miliardi spesi in istruzione, lingue e strumenti OOP, OOP non ha migliorato la produttività degli sviluppatori o l'affidabilità del software, né ha ridotto i costi di sviluppo. Poche persone usano OOP in qualsiasi 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; mette le funzioni per un tipo di record nel loro piccolo spazio dei nomi.

Ho scritto una grande quantità di codice per un'ampia varietà di applicazioni. Sebbene ci siano stati luoghi in cui il vero sottotitolo sostituibile ha svolto un ruolo prezioso nell'applicazione, questi sono stati piuttosto eccezionali. In generale, anche se viene dato molto servizio labiale per parlare di "riutilizzo", la realtà è che a meno che un pezzo di codice non faccia esattamente quello che si desidera che faccia, c'è un "riutilizzo" molto conveniente. È estremamente difficile progettare le classi per essere estensibili nel modo giusto , e quindi il costo dell'estensione è normalmente così grande 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 - che possiamo modellare le cose con una certa tassonomia di classe - mi sembra fondamentalmente imperfetta (posso sedermi su un tavolo, un tronco d'albero, un cofano di un'auto , il grembo di qualcuno - ma non uno di quelli è una sedia). Anche se ci spostiamo su domini più astratti, la modellazione OO è spesso difficile, controintuitiva e, in definitiva, non utile (considera gli esempi classici di cerchi / ellissi o quadrati / rettangoli).

Quindi cosa mi sto perdendo qui? Dov'è il valore di OOP e perché tempo e denaro non sono riusciti a migliorare il software?


11
La tua analogia è un'astrazione troppo elevata per il tuo "caso d'uso" previsto; tavolo, tronco d'albero, cofano, il grembo di qualcuno sono composizioni di molecole, atomi, protoni, neutroni, elettroni, che formano una superficie sufficientemente grande per far riposare il sedere contro la forza di gravità.
Icelava,

38
Non importa quante volte questo stesso thread viene avviato, genera sempre molto interesse (nonostante il fatto che i duplicati di solito non siano tollerati qui). E, naturalmente, la risposta scelta è sempre quella che concorda con l'opinione iniziale del richiedente.
TM.

4
Il problema con OOP è il fallimento nel metterlo nel contesto. È eccellente per alcuni scopi, non per tutti gli scopi. E 'un ottimo strumento. È un pessimo vangelo.
Mike Dunlavey,

16
Mi dispiace ma non riesco a scuotere la sensazione che non hai mai programmato usando alcun tipo di linguaggio. Ecco perché: OOP è la base operativa per le librerie dei componenti di base in tutti gli ambienti moderni (Java, .NET, Python, Ruby - solo per citarne alcuni di quelli del flusso principale). Tutte le librerie di base vengono riutilizzate quotidianamente, quindi se ciò non conta non so cosa. Quindi non fraintendetemi qui, ma riutilizzo del codice se un dato di fatto - e estremamente comune! Non voglio che questo sembri offensivo in alcun modo - sto solo facendo un punto qui.
Matthias Hryniszak,

2
@George Jempty: è stato Joel Spolsky in "Come Microsoft ha perso la guerra API" ( joelonsoftware.com/articles/APIWar.html ), titolo del brano è "Le trasmissioni automatiche vincono il giorno".
GodsBoss,

Risposte:


24

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

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

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

Che proviene da "On the Usability of OO Representations" di Communications of the ACM October 2000. Gli articoli confronta principalmente OO con l'approccio orientato al processo. C'è molto studio su come le persone che lavorano con il metodo OO "pensano" (Int. J. di 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 all'approccio OO che lo rende più adatto di un approccio procedurale più tradizionale.


18
Funziona bene Quello che non può fare è forzare i programmatori cattivi a scrivere un buon codice. C'è una tonalità periodica e piangere contro di essa per questo motivo.
caos,

6
@melaos: il sommario è nel mezzo. OOP è uno strumento nel toolkit, non l'unico, e non c'è sostituto per formazione, esperienza e giudizio.
Mike Dunlavey,

44
Trovo divertente quando qualcuno pubblica una "Domanda" per argomentare un punto, quindi accetta la prima risposta che supporta il suo punto, anche se ci sono domande più votate a sostegno del contrario. La natura umana è bella.
Bill K,

3
@melaos, il riassunto (almeno di quegli articoli) è che nulla suggerisce che OO sia un modo naturale di pensare per le persone, e quindi non intrinsecamente superiore a qualsiasi altro modo in cui si possano costruire programmi.
Svend,

6
@ Bill K: è stata una delle poche risposte a fornire citazioni piuttosto che agitando la mano e la semplice insistenza che OO "deve" essere migliore. Se la letteratura referenziata supporta l'idea che OO non rappresenta alcun miglioramento o beneficio particolare, e quindi supporta la mia posizione originale, non sono sicuro del motivo per cui dovrei ignorarlo. Potete fornire riferimenti simili che contrastano il mio PO?
DrPizza,

119

Il mondo reale non è "OO" e l'idea implicita in OO - che possiamo modellare le cose con una certa tassonomia di classe - mi sembra fondamentalmente imperfetta

Mentre questo è vero ed è stato osservato da altre persone (prendi Stepanov, inventore della STL), il resto non ha senso. OOP può essere difettoso e certamente non è un proiettile d'argento ma rende le applicazioni su larga scala molto più semplici perché è un ottimo modo per ridurre le dipendenze. Naturalmente, questo è vero solo per il "buon" design OOP. Il design sciatto non darà alcun vantaggio. Ma un buon design disaccoppiato può essere modellato molto bene usando OOP e non usando altre tecniche.

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


10
Trovo interessante che questo abbia più voti positivi rispetto alla domanda e una risposta approvata, combinate.
Brad Gilbert,

15
Trovo che il sistema di tipi di Haskell sia molto più intuitivo di OO.
axblount,

4
@Konrad: "ma rende le applicazioni su larga scala molto più semplici" - hmmm, non sono sicuro che sia vero. Li rende più sostenibili, nel senso che chnaging di una cosa non dovrebbe spezzarne un'altra, ma più semplice? Questo è un bel da ingoiare ...
Mitch Wheat

2
@BradGilbert: ovviamente il richiedente ha selezionato una risposta che si allinea perfettamente con l'opinione nella sua domanda iniziale. Il che solleva la domanda, perché preoccuparsi di porre la domanda se hai già deciso la tua risposta?
TM.

2
@Mitch: direi che non puoi (ad oggi) scrivere applicazioni su larga scala senza un qualche tipo di orientamento agli oggetti. Su larga scala qui è> 1M LOC.
Konrad Rudolph,

45

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


7
Ben fatto! E così vero.
Toon Krijthe,

1
Giusto. Ma poi non risolve il problema "reinventare la ruota", che è onestamente serio nello sviluppo del software - invece di avere una libreria che ha N coppie di occhi in cerca di difetti, abbiamo N librerie con un paio di occhi che fanno così. Ci sono così tante classi utilizzabili che puoi costruire prima che tu debba iniziare a riutilizzarle. E OOP secondo la mia opinione educata, è fondamentalmente imperfetto dal riutilizzo del prefisso. Nasconde i dati e li "sposa" ai metodi, rendendo effettivamente tali dati inaccessibili o difficilmente interoperabili.
AMN

42

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

Sì, trovo che anche questo sia troppo diffuso. Questa non è una programmazione orientata agli oggetti. Si tratta di 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 interrompe molto rapidamente IMHO poiché in sostanza si sta ottenendo il peggio di entrambe le parole: 1) Programmazione procedurale senza aderire alla metodologia di programmazione strutturata comprovata e 2) OOP senza aderire alla metodologia OOP comprovata.

OOP fatto bene è una cosa bellissima. Rende i problemi molto difficili facili da risolvere, e per i non iniziati (non cercando di sembrare pomposo lì), può quasi sembrare magia. Detto questo, OOP è solo uno strumento nella cassetta degli attrezzi delle metodologie di programmazione. Non è la fine tutta la metodologia. Capita solo di adattarsi bene alle grandi applicazioni aziendali.

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


32

Il riutilizzo non dovrebbe essere un obiettivo di OOP - o qualsiasi altro paradigma per quella materia.

Il riutilizzo è un effetto collaterale di un buon design e 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 fare noi stessi. Questo è pragmatismo.

Il pensiero di OO come un nuovo modo di riutilizzare l'eredità è fondamentalmente imperfetto. Come notate le violazioni di LSP abbondano. Invece, OO è correttamente considerato 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. Questo ci permette di avere regole come "Questo dovrebbe essere modificato solo usando ..." imposto dal compilatore, piuttosto che revisione del codice.

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


3
vero sul riutilizzo e OO come preoccupazioni separate.
Dan Rosenstark,

28

Vergognando sui religiosi, ma direi che stai dipingendo un quadro troppo cupo dello stato della moderna OOP. Direi che in realtà ha ridotto i costi, fatta di grandi progetti software gestibile, e così via. Ciò non significa che abbia 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 certamente ridotto la quantità di codice spaghetti presente nel mondo.

Riesco a pensare a decine di librerie dalla parte superiore della mia testa che sono meravigliosamente riutilizzabili e che hanno risparmiato tempo e denaro che non possono mai essere calcolati.

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


2
Ti ho appena dato un voto che ti ha spinto oltre 2000 punti - speriamo che rimanga. : P
Jason Bunting,

5
È raro vedere che OOP viene insegnato in modo efficace.
Jon W,

La tua risposta suona molto simile a quella fornita dai trainer Agile / Scrum quando viene chiesto se ha senso: "è molto utile se lo fai bene; se fallisci, allora devi sbagliare". È facile gettare parole come "riutilizzabile" e "mantenibile", ma non è nemmeno facile quantificare queste qualità nel codice reale, né esiste una ricetta che ti spieghi come scrivere un buon OOP (nonostante migliaia di libri tentino di farlo) . Abbiamo anche la cattiva abitudine di ignorare apparentemente l'hardware, il che porta a prestazioni orribili sull'altare di evitare l'ottimizzazione prematura.
Tom,

21

Penso che l'uso di oggetti di contesto opachi (HANDLEs in Win32, FILE * s in C, per nominare due esempi ben noti: l'inferno, HANDLE vive dall'altra parte della barriera in modalità kernel, e in realtà non si ottiene molto più incapsulato di quello) si trova anche nel codice procedurale; Faccio fatica a vedere come questo sia qualcosa di particolare per OOP.

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

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


1
Stavo per pubblicare qualcosa di molto simile.
Brad Gilbert,

Sono d'accordo che è possibile utilizzare i concetti OOP senza una sintassi speciale, ma d'altra parte, non penso che WinAPI sia un buon esempio di concetti OOP.
Lena Schimmel,

14

È un paradigma di programmazione. Progettato per rendere più semplice per noi semplici mortali suddividere un problema in pezzi più piccoli e lavorabili.

Se non lo trovi utile .. Non usarlo, non pagare per l'allenamento ed essere felice.

D'altra parte lo trovo utile, quindi lo farò :)


14

Relativamente alla semplice programmazione procedurale, il primo principio fondamentale di OOP è la nozione di occultamento e incapsulamento delle informazioni. Questa idea porta alla nozione della classe che separa l'interfaccia dall'implementazione. Questi sono concetti estremamente importanti e la base per mettere in atto un framework per pensare alla progettazione del programma in un modo diverso e migliore (penso). Non si può davvero discutere contro quelle proprietà: non c'è alcun compromesso ed è sempre un modo più pulito di modulare le cose.

Anche altri aspetti della OOP, tra cui eredità e polimorfismo, sono importanti, ma come altri hanno accennato, quelli sono comunemente usati troppo. cioè: a volte le persone usano l'eredità e / o il polimorfismo perché possono, non perché dovrebbero avere. Sono concetti potenti e molto utili, ma devono essere usati con saggezza e non sono vantaggi automatici vincenti di OOP.

Relativo al riutilizzo. Accetto che il riutilizzo sia esaurito per OOP. È un possibile effetto collaterale di oggetti ben definiti, in genere di classi più primitive / generiche ed è un risultato diretto dei concetti di incapsulamento e occultamento delle informazioni. È potenzialmente più facile da riutilizzare perché le interfacce di classi ben definite sono semplicemente più chiare e in qualche modo auto-documentate.


1
Il riutilizzo è qualcosa di grave per gli sviluppatori di software, non è, indipendentemente dal paradigma che usano, sia OO o funzionale o qualunque altra cosa? Ciò è in conflitto con i requisiti in continua evoluzione del software e la domanda sembra essere quella di rendere i progetti flessibili.
Geoglyph

"nozione della classe che separa l'interfaccia dall'implementazione" --- Pensavo che le interfacce fossero interfacce e le classi fossero implementazioni? Forse sono solo un pensatore troppo orientato al processo, ma immagino sia il polimorfismo, la varianza nel codice con l'uniformità in uso, che è il kicker di OOP; Immagino che "un gruppo di funzioni C" separa un'interfaccia da un'implementazione così come "una classe java". Forse mi sbaglio tutto?
Jonas Kölker,

2
@Jonas - Alle tue "un mucchio di funzioni C" --- Sono d'accordo che possono separare un'interfaccia da un'implementazione, e a quel punto inizia a essere OOP. Se l'esempio continua a definire una struttura C su cui opera l'API, in pratica hai creato l'incapsulamento (soprattutto se l'API opera opacamente sulla struttura) ... e poi è davvero OOP in C.
Tall Jeff

12

Il problema con OOP è che è stato ipervenduto.

Come originariamente concepito da Alan Kay, era un'ottima alternativa alla pratica precedente di disporre di dati non elaborati e routine globali.

Quindi alcuni tipi di consulenti di gestione si sono aggrappati a esso e lo hanno venduto come il messia del software, e dopo che lemming-like, il mondo accademico e l'industria sono crollati.

Ora stanno cadendo come lemming dopo che altre buone idee sono state vendute, come la programmazione funzionale.

Quindi cosa farei diversamente? Un sacco, e ho scritto un libro su questo. (È esaurito - Non ottengo un centesimo, ma puoi ancora ottenere copie.) Amazon

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

È molto diverso e si basa sulla teoria dell'informazione (a un livello che chiunque può capire). Dice che la programmazione può essere vista come un processo di definizione delle lingue, e l'abilità nel farlo è essenziale per una buona programmazione.

Aumenta il concetto di linguaggi specifici di dominio (DSL). È perfettamente d'accordo con DRY (non ripeterti). Dà un grande pollice in su alla generazione del codice. Ne risulta un software con una struttura di dati enormemente inferiore a quella tipica delle applicazioni moderne.

Cerca di rinvigorire l'idea che la via da percorrere sia nell'inventiva e che anche le idee ben accettate debbano essere messe in discussione.


Freddo. Dato che il libro è esaurito, non vorresti fornire PDF, vero? Amazon spedisce LENTAMENTE in Argentina ...
Dan Rosenstark il

Ho il sospetto che da qualche parte nelle prime fasi del processo, alcuni programmatori buoni cerato rapsodica di quello che potrebbero fare con OOP, e qualcuno li Overheard e pensò che questo significava chiunque sia poteva e voleva fare lo stesso.
caos,

@Daniel: buon suggerimento. Ci lavorerò su e vedrò se posso collegarlo al mio blogspot. Lo troverai un po 'vecchio stile, perché era nel '94, ma i principi non sono cambiati.
Mike Dunlavey,

1
@Mike Dunlavey Gentile signore, posso supportare la curiosità di @yar di sapere se c'è la possibilità di leggere / ottenere il tuo libro [almeno in parte] via Internet? Siccome sembra che il modo in cui le specifiche / implementazioni del software [componente] proposti / sviluppate corrispondano strettamente a quello [che ho recentemente riconosciuto] vorrei imparare o essere insegnato (al contrario, beh, il modo 'cargo' introdotto da scritti OO tradizionali ma dolorosamente ambigui). Grazie in anticipo [e saluti dalla Russia :)].
mlvljr

1
@mlvljr: OK. Il modo più veloce potrebbe essere semplicemente quello di scansionarlo e creare un grande file pdf. Vedrò se ci riuscirò nei prossimi giorni. Non lasciarmi dimenticare [sincere condoglianze per i recenti avvenimenti a Mosca e saluti dal fradicio Massachusetts].
Mike Dunlavey,

11

HANDLEs (e il resto di WinAPI) è OOP!

Ma lo sono? Non sono ereditabili, non sono certamente sostituibili, mancano di classi ben definite ... Penso che non siano molto "OOP".

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

I manici potrebbero non essere ereditabili, ma poi c'è finalin Java. A loro non manca una classe, sono un segnaposto per la classe: ecco cosa significa la parola "maneggiare". Guardando architetture come MFC o .NET WinForms è immediatamente ovvio che, tranne per la sintassi, nulla è molto diverso da WinAPI.


WINAPI non è OOP. Mostra solo un modo di scrivere un codice procedurale estensibile. Le buone tecniche sono buone, indipendentemente dal fatto che siano OOP o meno. Posso scrivere programmi WINAPI in C e usare le stesse tecniche nel mio codice, quindi immagino che C sia OOP.
Bruceatk,

3
Potrebbe non essere quello che Alan Kay aveva in mente (cercalo su Google!) Ma è comunque OOP.
Konrad Rudolph,

11

Sì, OOP non ha risolto tutti i nostri problemi, mi dispiace per quello. Stiamo comunque lavorando a SOA che risolverà tutti questi problemi.


4
Non hai sentito? SOA è il passato. Oggi è il cloud computing che sarà il nostro salvatore.
DrPizza,

Mi chiedo davvero se le tue risposte siano ironiche o meno. Mi piace l'ironia, ma di solito viene votato, questo mi fa chiedere ...
Lena Schimmel,

Penso che questo sia ironico e non lo voterò. Ma non lo voterò neanche io! :-)
Yarik,

La domanda è abbastanza retorica, quindi questa è una risposta valida (e la migliore risposta).
Jeff Davis,

10

OOP si presta bene alla programmazione di strutture informatiche interne come "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 stiamo lavorando con concetti di business come fattura, dipendente, lavoro, ordine. Questi non si prestano così bene a OOP perché gli "oggetti" sono più nebulosi, soggetti a modifiche in base alla reingegnerizzazione aziendale e così via.

Il caso peggiore è quando OO viene applicato con entusiasmo ai database, compresi i grandiosi "miglioramenti" di OO ai database SQL, che sono giustamente ignorati, tranne dai nomi dei database che ritengono che debbano essere il modo giusto di fare le cose perché sono più recenti.


Questo è tutto vero, ma ... forse, il fatto che OOP possa semplificare ALCUNI aspetti non correlati al business di un'applicazione (come l'implementazione dell'interfaccia utente) è esattamente uno dei motivi principali per cui uno sviluppatore (finalmente!) Può dedicare più tempo a lavorare sul business aspetti correlati?
Yarik,

10

Nella mia esperienza di revisione del codice e progettazione di progetti che ho passato, il valore di OOP non è pienamente realizzato perché molti sviluppatori non hanno correttamente concettualizzato il modello orientato agli oggetti nelle loro menti. Quindi non programmano con il design OO, molto spesso continuano a scrivere un codice procedurale top-down che rende le classi un design piuttosto piatto . (se puoi persino chiamare quel "design" in primo luogo)

È piuttosto spaventoso osservare come i piccoli colleghi sappiano cosa siano una classe o un'interfaccia astratte, per non parlare della corretta progettazione di una gerarchia ereditaria per soddisfare le esigenze aziendali.

Tuttavia, quando è presente un buon design OO, è solo pura gioia leggere il codice e vederlo naturalmente inserirsi in componenti / classi intuitivi. Ho sempre percepito l'architettura e il design del sistema come progettare i vari reparti e lavori del personale in un'azienda - tutti sono lì per compiere un certo lavoro nel grande schema delle cose, emettendo la sinergia necessaria per spingere l'organizzazione / sistema in avanti.

Questo, ovviamente, è abbastanza raro purtroppo. Come il rapporto tra oggetti fisici meravigliosamente progettati e oggetti orribilmente progettati nel mondo, lo stesso si può dire praticamente dell'ingegneria e della progettazione del software. Avere a disposizione i buoni strumenti non conferisce necessariamente buone pratiche e risultati.


1
Non ho mai raggiunto la fase di pura gioia procedurale o OOP durante la lettura del codice. :)
Bruceatk,

1
Gioia pura, no, ma forse un piccolo sorriso?
Dan Rosenstark,

9

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


2
Non hai mai dovuto usare un linguaggio OO senza interfacce, vero? Sei fortunato.
finnw,

No non lo sono. Sono cose che non sono state progettate per stare seduti, quindi penso che siano fedeli all'analogia, non sarebbero state scritte per implementare l'interfaccia ISittable. Provengono da una libreria di terze parti e ora che stai scrivendo un progetto che coinvolge un dominio che include la seduta, ti accorgi che dovrai scrivere oggetti adattatore per avvolgerli per renderli ISittable. Vedere? Non molto simile al mondo reale.
EricS,

8

Penso che quelle cose del mondo reale siano oggetti

Tu fai?

Quali metodi ha una fattura? Oh aspetta. Non può pagare se stesso, non può inviare se stesso, 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 della parola. Gli oggetti OO sono un peculiare accoppiamento di stato e comportamento che possono agire da soli. Non è qualcosa che è abbondante nel mondo reale.


2
Prendi qualsiasi macchina, dispositivo elettronico o essere vivente, quelli sono tutti "accoppiamenti di stato e comportamento".
TM.

1
Concordo sul fatto che metodi come Send () o Pay () siano "innaturali" per le fatture. Ma, per esempio, che dire dell'importo totale come attributo derivato ma INERENTE di una fattura? Non è un esempio di ciò che OOP consente di modellare in modo molto "naturale" anche per entità della vita reale totalmente inerte? Non un grande risultato da solo, ma comunque ...
Yarik,

@Yarik: queste entità "inerti" portano a un design basato su oggetti. Per me, l'unica vera OO è la simulazione, in cui gli oggetti "possono agire da soli" , come afferma questa risposta. Se OO è l'unico modo trattabile per realizzare qualcosa, va bene, ma per il resto non possiamo attenerci a qualcosa di più semplice e più simile al problema da risolvere?

7

Ho scritto il codice OO negli ultimi 9 anni circa. Oltre a usare la 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 (cioè codice liberamente accoppiato, altamente coeso con una chiara separazione delle preoccupazioni).

Penso che il punto in cui si rompe OO sia quando le persone creano erirarchie di classe profondamente annidate. Questo può portare a complessità. Tuttavia, incorporare la fictionalità comune in una classe base, quindi riutilizzare che in altre classi discendenti è una cosa profondamente elegante, IMHO!


7

In primo luogo, le osservazioni sono piuttosto sciatte. Non ho dati sulla produttività del software e non ho buone ragioni per credere che non stia aumentando. Inoltre, poiché ci sono molte persone che abusano di OO, un buon uso di OO non causerebbe necessariamente un miglioramento della produttività anche se OO fosse la cosa più grande dal burro di arachidi. Dopotutto, un chirurgo cerebrale incompetente è probabilmente peggio di niente, ma uno competente può essere prezioso.

Detto questo, OO è un modo diverso di organizzare le cose, allegando codice procedurale ai dati piuttosto che far funzionare il codice procedurale sui dati. Questa dovrebbe essere almeno una piccola vittoria da sola, poiché ci sono casi in cui l'approccio OO è più naturale. Dopotutto, nulla impedisce a nessuno di scrivere un'API procedurale in C ++, quindi l'opzione di fornire oggetti rende 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 proceduralmente e aggiungo un nuovo tipo di cose simili ma non identiche a una precedente, devo cambiare il codice procedurale. In un sistema OO, eredito la funzionalità, cambio ciò che mi piace e il nuovo codice viene automaticamente utilizzato a causa del polimorfismo. Ciò aumenta la località dei cambiamenti e questa è una buona cosa.

Il rovescio della medaglia è che un buon OO non è gratuito: richiede tempo e sforzi per impararlo correttamente. Dal momento che è una parola d'ordine importante, ci sono molte persone e prodotti che lo fanno male, solo per il gusto di farlo. Progettare un'interfaccia di buona classe non è più semplice di una buona API procedurale, e ci sono tutti i tipi di errori facili da fare (come le gerarchie di classi profonde).

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


Mi piace il tuo ultimo paragrafo il migliore.
Mike Dunlavey,

6

@Sean

Tuttavia, incorporare la fictionalità comune in una classe base, quindi riutilizzare che in altre classi discendenti è una cosa profondamente elegante, IMHO!

Ma gli sviluppatori "procedurali" lo fanno da decenni comunque. La sintassi e la terminologia potrebbero differire, ma l'effetto è identico. C'è di più in OOP oltre a "riutilizzare funzionalità comuni in una classe base", e potrei persino spingermi fino al punto di dire che è difficile da descrivere come OOP; chiamare la stessa funzione da diversi bit di codice è una tecnica vecchia quanto la sottoprocedura stessa.


6

@Konrad

OOP può essere imperfetto e certamente non è un proiettile d'argento ma rende le applicazioni su larga scala molto più semplici perché è un ottimo modo per ridurre le dipendenze

Questo è il dogma. Non vedo ciò che rende OOP significativamente migliore in questo senso rispetto alla programmazione procedurale del vecchio. Ogni volta che faccio una chiamata di procedura mi sto isolando dalle specifiche dell'implementazione.


6

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

Non importa che una fattura non sia in realtà un "oggetto" con funzioni che può svolgere da sola: l'istanza dell'oggetto può esistere solo per eseguire funzioni sui dati senza dover sapere quale tipo di dati è effettivamente presente. La funzione "invoice.toJson ()" può essere chiamata con successo senza dover sapere che tipo di dati è "fattura" - il risultato sarà Json, non importa se proviene da un database, XML, CSV o anche un altro oggetto JSON . Con le funzioni procedurali, all'improvviso devi saperne di più sui tuoi dati e finire con funzioni come "xmlToJson ()", "csvToJson ()", "dbToJson ()", ecc. Alla fine diventa un casino completo e un ENORME mal di testa se si modifica il tipo di dati sottostante.

Il punto di OOP è nascondere l'implementazione effettiva sottraendola. Per raggiungere questo obiettivo, è necessario creare un'interfaccia pubblica. Per semplificare il tuo lavoro durante la creazione di tale interfaccia pubblica e mantenere le cose ASCIUTTE, devi utilizzare concetti come classi astratte, eredità, polimorfismo e modelli di progettazione.

Quindi, per me, il vero obiettivo prioritario di OOP è semplificare la manutenzione e le modifiche future del codice. Ma anche oltre, può davvero semplificare molto le cose se fatto correttamente in modi che il codice procedurale non potrebbe mai. Non importa se non corrisponde al "mondo reale" - la programmazione con il codice non interagisce comunque con gli oggetti del mondo reale. OOP è solo uno strumento che semplifica e velocizza il mio lavoro: ci proverò ogni giorno.


5

@CodingTheWheel

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

Non so se è davvero sorprendente, però. Penso che approcci tecnicamente validi (LSP sia la cosa ovvia) rendano difficile da usare , ma se non utilizziamo tali approcci rende comunque il codice fragile e inestensibile (perché non possiamo più ragionare su di esso). E penso che i risultati controintuitivi che OOP ci portano a rendere sorprendente il fatto che le persone non lo raccolgano.

Più significativamente, 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 chiari, potrebbe valere la pena perseverare nonostante la difficoltà, ma questo non sembra essere il caso.


La "formazione adeguata" deve essere molto lunga, astratta e complessa in questi giorni. Lo so: insegno programmazione. Decenni fa, molte persone potevano imparare a fare una sorta di programmazione. Penso che non sia più vero.

5

@Jeff

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

Qual è l'implementazione più nascosta: gli iostreams di C ++ o FILE * di C?

Penso che l'uso di oggetti di contesto opachi (HANDLEs in Win32, FILE * s in C, per nominare due esempi ben noti: l'inferno, HANDLE vive dall'altra parte della barriera in modalità kernel, e in realtà non si ottiene molto più incapsulato di quello) si trova anche nel codice procedurale; Faccio fatica a vedere come questo sia qualcosa di particolare per OOP.

Suppongo che possa essere una parte del motivo per cui sto lottando per vedere i benefici: le parti che sono ovviamente buone non sono specifiche per OOP, mentre le parti che sono specifiche per OOP non sono ovviamente buone! (questo non vuol dire che sono necessariamente cattivi, ma piuttosto che non ho visto le prove che sono ampiamente applicabili e costantemente vantaggiosi).


5

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 lo fa. Freddo. Chi può negare i dati?

Credo ancora che OO sia non-OO come programmare con le funzioni è programmare tutto in linea.

(E dovrei sapere, come ho iniziato con GWBasic.) Quando si refactoring il codice per usare le funzioni, variable2654diventa variable3il metodo in cui ci si trova. O, meglio ancora, ha un nome che si può capire e se la funzione è breve , si chiama value ed è sufficiente per la piena comprensione.

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

Quando si refactoring del codice per essere veramente OO, b, c, q, e Zdiventare this, this, thise this. E poiché non credo nell'uso della thisparola chiave, puoi eliminare miglia di codice. In realtà, puoi farlo anche se lo usi this.



Non penso che OO sia una metafora naturale.

Non penso che il linguaggio sia una metafora naturale, né penso che gli "odori" di Fowler siano meglio di dire "questo codice ha un cattivo sapore". Detto questo, penso che OO non riguardi metafore naturali e le persone che pensano che gli oggetti appena spuntati su di te non abbiano sostanzialmente ragione. Definisci l'universo degli oggetti, e gli universi degli 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 usano gli oggetti naturali del cliente / dominio come oggetti di programmazione non abbiano il potere di ridefinire l'universo.

Ad esempio, quando si esegue un sistema di prenotazione di una compagnia aerea, ciò che si chiama una prenotazione potrebbe non corrispondere affatto a una prenotazione legale / commerciale.



Alcuni dei concetti di base sono strumenti davvero interessanti

Penso che la maggior parte della gente 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 / eredità, inizi a trovare usi dove si adatta come un guanto / calzino / lenti a contatto. Gli strumenti di OO sono molto potenti. Penso che l'ereditarietà singola sia assolutamente necessaria affinché le persone non si lascino trasportare, nonostante il mio software multi-ereditarietà.



Qual è il punto di 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.

OOP è destinato a essere frainteso dalla maggior parte degli sviluppatori

Questo perché è un processo che apre gli occhi come la vita: capisci 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 invece il modello Facciata .



Per quanto riguarda il tuo mini-saggio / domanda

Volevo menzionare che hai ragione. La riusabilità è un sogno irrealizzabile, per la maggior parte. Ecco una citazione di Anders Hejilsberg sull'argomento (geniale) da qui :

Se chiedi ai programmatori principianti di scrivere un controllo calendario, spesso pensano a se stessi: "Oh, scriverò il miglior controllo calendario del mondo! Sarà polimorfico rispetto al tipo di calendario. Avrà displayer, e munger, e questo, quello e l'altro. " Devono spedire un'applicazione di calendario tra due mesi. Hanno messo tutta questa infrastruttura nel controllo e poi hanno trascorso due giorni a scrivere un'applicazione scadente del calendario su di essa. Penseranno: "Nella prossima versione dell'applicazione, farò molto di più".

Una volta che iniziano a pensare a come implementeranno effettivamente tutte queste altre concretizzazioni del loro disegno astratto, tuttavia, si scopre che il loro disegno è completamente sbagliato. E ora si sono dipinti in un angolo e devono buttare via tutto. L'ho visto ancora e ancora. Sono fermamente convinto di essere minimalista. A meno che tu non risolva effettivamente il problema generale, non provare a creare un framework per risolverne uno specifico, perché non sai come dovrebbe apparire quel framework.


4

Hai mai creato una finestra usando WinAPI?

Più volte di quanto mi importi di ricordare.

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

Quindi saprai anche che non invia messaggi per conto suo, il che è un grande vuoto. Ha anche una sottoclasse scadente.

I manici potrebbero non essere ereditabili, ma poi c'è un finale in Java. A loro non manca una classe, sono un segnaposto per la classe: ecco cosa significa la parola "maneggiare". Guardando architetture come MFC o .NET WinForms è immediatamente ovvio che, fatta eccezione per la sintassi, nulla è molto diverso da WinAPI.

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

È davvero così? I pezzi migliori di OOP sono solo ... codice procedurale tradizionale? Questo è il grosso problema?


Devi ricordare che l'interfaccia Win32 era sostanzialmente una reimplementazione di Win16. Che è stato progettato oltre due decenni fa.
Brad Gilbert,

Quando stavo imparando a programmare al college, principalmente in C ma anche in altre lingue, ci venivano insegnate alcune idee di base ed esposte ad alcune piattaforme, ma si comprendeva che la responsabilità generale di ideare progetti, strutture, migliori pratiche, ecc. dipenderà da noi sul posto di lavoro. Abbiamo imparato tecniche, non visioni del mondo. Con OO, devi imparare una religione prima di poter fare qualcosa di utile e questo determina completamente come vedi le soluzioni. Non penso sia proprio corretto.

4

Sono completamente d'accordo con la risposta di InSciTek Jeff , aggiungerò solo i seguenti perfezionamenti:

  • Nascondimento e incapsulamento delle informazioni: critico per qualsiasi codice gestibile. Può essere fatto facendo attenzione in qualsiasi linguaggio di programmazione, non richiede funzionalità OO, ma farlo renderà il tuo codice leggermente simile a OO.
  • Ereditarietà: esiste un dominio di applicazione importante per il quale tutte quelle relazioni OO sono un tipo e contengono una corrispondenza perfetta: le interfacce utente grafiche. Se provi a creare GUI senza il supporto del linguaggio OO, finirai comunque per creare funzionalità simili a OO, ed è più difficile e più soggetto a errori senza supporto del linguaggio. Glade (recentemente) e X11 Xt (storicamente) per esempio.

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


Sì, penso che dovresti usare OOP per oggetti, programmazione funzionale per funzioni ...
Svante

4

Credo che la qualità più vantaggiosa di OOP sia il nascondimento / gestione dei dati. Tuttavia, ci sono MOLTI esempi in cui 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. Tuttavia, se ciò renderà il tuo codice più organizzato / più facile da leggere, allora dovresti assolutamente farlo.

Un ottimo esempio pratico in cui OOP è molto utile è con una classe di "prodotto" e oggetti che utilizzo sul nostro sito Web. Poiché ogni pagina è un prodotto e ogni prodotto ha riferimenti ad altri prodotti, può diventare molto confuso su quale prodotto si riferiscono ai dati che hai. Questa variabile "strURL" è il collegamento alla pagina corrente o alla home page o alla pagina delle statistiche? Sicuramente 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 avessi appena chiamato quelle funzioni e supponessi che i dati attuali fossero disponibili, chissà che tipo di male si sarebbe verificato. Inoltre, se dovessi trasferire le variabili corrette in tali funzioni, tornerò al problema di disporre di tutti i tipi di variabili per i diversi prodotti.

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

Però. Il grosso problema con 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. La maggior parte delle volte l'accesso diretto a tali tabelle è perfettamente comprensibile nelle circostanze in cui lo uso e OOP renderebbe effettivamente più difficile / noioso arrivare alla funzionalità principale di ciò che sta accadendo.

Credo che un modello ibrido di oggetti sia utile e procedurale in cui la pratica sia il metodo di codifica più efficace. È un peccato che abbiamo tutte queste guerre di religione in cui le persone sostengono di usare un metodo a spese degli altri. Sono entrambi bravi ed entrambi hanno il loro posto. Il più delle volte, ci sono usi per entrambi i metodi in ogni progetto più grande (in alcuni progetti più piccoli, un singolo oggetto o alcune procedure potrebbero essere tutto ciò di cui hai bisogno).


3

Non mi interessa il riutilizzo tanto quanto la leggibilità. Quest'ultimo significa che il codice è più facile da modificare. Questo vale da solo in oro nell'arte di costruire software.

E OO è un modo dannatamente efficace per rendere leggibili i tuoi programmi. Riutilizzo o nessun riutilizzo.


2

"Il mondo reale non è" OO ","

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

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 cose del mondo reale come fatture, ordini di spedizione, richieste di risarcimento assicurativo e quant'altro, penso che quelle cose del mondo reale siano oggetti. Ho una pila sulla mia scrivania, quindi devono essere reali.


2

Il punto di OOP è dare al programmatore un altro mezzo per descrivere e comunicare una soluzione a un problema nel codice a macchine e persone. La parte più importante di ciò è la comunicazione alle persone. OOP consente al programmatore di dichiarare cosa significano nel codice attraverso regole applicate nel linguaggio OO.

Contrariamente a molti argomenti su questo argomento, i concetti OOP e OO sono diffusi in tutto il codice, incluso il codice in linguaggi non OOP come C. Molti programmatori avanzati non OO approssimano le caratteristiche degli oggetti anche in linguaggi non OO.

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

La maggior parte della scrittura del codice non è la comunicazione con la macchina, quella parte è facile, la maggior parte è la comunicazione con i programmatori umani.

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.