OOP sta diventando più facile o più difficile? [chiuso]

36

Quando i concetti di programmazione orientata agli oggetti sono stati introdotti ai programmatori anni fa, sembra interessante e la programmazione era più pulita. OOP era così

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);

Era più facile da capire con un nome auto-descrittivo

Ma ora OOP, con pattern come Data Transfer Objects, Value Objects, Repository, Dependency Injection ecc, è diventato più complesso. Per ottenere quanto sopra, potrebbe essere necessario creare diverse classi (ad esempio, abstract, factory, DAO ecc.) E implementare diverse interfacce

Nota: non sono contraria alle best practice che semplificano la collaborazione, i test e l'integrazione

    
posta tunmise fasipe 10.06.2012 - 16:17
fonte

8 risposte

35

Lo stesso OOP non è cambiato molto dal suo inizio. Alcuni nuovi angoli sono stati esplorati, ma i principi fondamentali sono rimasti gli stessi. Se non altro, la conoscenza collettiva acquisita nel corso degli anni rende la vita del programmatore più facile che difficile. I modelli di progettazione non sono un ostacolo; forniscono una cassetta degli attrezzi di soluzioni a problemi standard, distillati da anni e anni di esperienza.

Quindi perché oggi percepisci l'OOP come più complesso di quando lo hai iniziato?

Un motivo potrebbe essere che il codice a cui sei esposto diventa più complesso - non perché l'OOP sia diventato più complesso, ma perché tu sei avanzato sulla scala di apprendimento, e puoi leggere basi di codice più grandi e più complesse.

Un altro motivo potrebbe essere che, mentre il paradigma della complessità non è cambiato, le dimensioni e la complessità di un progetto software medio possono benissimo avere. Con la potenza di elaborazione disponibile sui telefoni cellulari di grado cliente che sarebbe stato il sogno bagnato di uno sviluppatore su un server meno di due decenni fa, il pubblico in genere si aspettava una GUI animata slick per l'app per il lancio più economico, e l'entrata -levelo PC desktop è più potente di un "supercomputer" del 1980, è naturale che la barra sia stata sollevata sin dai primi giorni di Smalltalk e C ++.

E poi c'è il fatto che nelle applicazioni moderne, la concorrenza e il parallelismo sono la norma piuttosto che l'eccezione e le applicazioni spesso hanno bisogno di comunicare tra macchine diverse, emettendo e analizzando un intero zoo di protocolli. Sebbene OOP sia ottimo come paradigma organizzativo, ha i suoi limiti, proprio come qualsiasi altro paradigma: ad esempio, non fornisce molta astrazione per la concorrenza (la maggior parte delle implementazioni è più o meno un ripensamento, o esternalizzata interamente alle librerie) e non è il miglior approccio possibile per la costruzione di parser e la trasformazione dei dati. La programmazione moderna spesso si scontra con i limiti del paradigma OOP e gli schemi di progettazione possono solo portarti a termine. (Personalmente, considero il fatto che abbiamo bisogno di schemi di progettazione un segno di questo - se il paradigma fornisse queste soluzioni in modo immediato, sarebbe più espressivo per questi problemi e le soluzioni standard sarebbero ovvie. nessun modello di progettazione per descrivere l'ereditarietà del metodo, perché è una caratteristica fondamentale di OOP, ma esiste un Pattern di fabbrica, perché OOP non fornisce un modo ovvio naturale di costruire oggetti polimorficamente e in modo trasparente.)

Per questo motivo, i linguaggi OOP più moderni incorporano funzionalità di altri paradigmi, che li rendono più espressivi e più potenti, ma anche più complessi. C # ne è l'esempio principale: ha ovvie radici OOP, ma caratteristiche come delegati, eventi, inferenza di tipo, tipi di dati varianti, attributi, funzioni anonime, espressioni lambda, generici, ecc., Provengono da altri paradigmi, in particolare la Programmazione funzionale .

    
risposta data 10.06.2012 - 17:35
fonte
17

No, sta diventando sempre più ipotecato. E hai ragione - nella chat SO C ++ facciamo spesso battute su AbstractSingletonFactoryProxyBeanBridgeAdapterManagers che vediamo nel codice Java.

Ma il buon codice non esibisce questa proprietà. Nel codice corretto, puoi comunque dire

std::stack<int> s;
s.push(5);
s.pop();
    
risposta data 10.06.2012 - 16:27
fonte
10

Direi che i problemi con la "complessità" che hai citato non hanno nulla a che fare con OOP. Ha più a che fare con la separazione delle preoccupazioni.

Molti anni fa ho lavorato su un sistema, in cui la classe dominio aveva la responsabilità di caricarsi dal database, ad es.

var userId = Request.QueryString["UserID"].ToInt();
var user = new User(userId);
user.Name = ...;
...
user.Save();

Questo è un codice molto chiaro. Nessun problema nel capire questo. Il problema tuttavia sarebbe in unità testare il codice. Vale a dire, come posso testare unitamente la classe User senza doverne caricare uno dal database? E come potrei testare questo codice di gestione delle richieste web senza avere accesso al database? Semplicemente non è possibile.

Ecco perché abbiamo un modello come un repository, per separare la responsabilità di gestire la logica di dominio da un utente dalla funzionalità di caricare e salvare effettivamente uno in un archivio dati. IOC aiuta a ridurre l'accoppiamento, rendendo anche il codice più verificabile, ecc.

Quindi, se torniamo all'esempio che scrivi, cosa faresti con lo stock dopo averlo creato? Salvalo nel database

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);
this.StockRepository.Add(stock);

Ecco fatto! Non vi è alcun movimento nella progressione di OOP che suggerisce che dovrebbe essere più difficile. Sfortunatamente, se si sceglie di utilizzare un mapper OR per il proprio codice di accesso ai dati, si potrebbe incorrere nel problema che il mappatore OR sta ponendo delle restrizioni su come è possibile scrivere il proprio sistema. Ma questa è un'altra questione.

Se sei nuovo a questi schemi, potresti aver bisogno di imparare un nuovo stile di programmazione. Ma questo stile di programmazione non è in alcun modo più difficile della programmazione OOP della vecchia scuola.

    
risposta data 10.06.2012 - 16:56
fonte
4

Nessuno dei due. I nostri problemi non sono davvero cambiati; la barra per codice accettabile è stata sollevata.

To achieve the above you may have to create several classes (e.g. abstract, factory, DAO etc) and Implement several interfaces

Non hai per farlo. Ma se non lo fai, i problemi sorgono; problemi che sono sempre stati lì. Ora, però, i programmatori hanno esperienza sufficiente per identificare quei problemi e fornire meccanismi per alleviarli (se necessario). Apprendiamo di più su queste e troveremo soluzioni migliori (vedi - le viste dei programmatori sul singleton ad esempio).

Ma devi anche rend contoere che l'introduzione dei programmatori a OO (o qualsiasi altra cosa per quella materia) tenderà a sorvolare sulle circostanze eccezionali. È semplicemente più facile spiegare il percorso felice e preoccuparsi del resto una volta che i principianti lo hanno eliminato. Non c'è un proiettile d'argento; quindi sì, suppongo che le cose sembreranno sempre più difficili quando quell'illusione idilliaca viene infranta ...

    
risposta data 11.06.2012 - 04:12
fonte
3

Gli esempi di "intro to OO" sono molto più semplici di un'applicazione del mondo reale. Hai solo bisogno di una classe per ottenere quanto sopra. Il problema è che non fa molto. Alcuni schemi di progettazione cercano di avvicinarsi (come ActiveRecord). Ma alla fine, qualsiasi esempio che non sia banale avrà più di una classe; va bene.

    
risposta data 10.06.2012 - 16:25
fonte
3

I linguaggi di programmazione che utilizzano OO oggi stanno cercando di soddisfare esigenze e ambienti complessi che continuano a cambiare. OO consente ai suoi utenti adottivi di nascondere vari livelli di complessità (tra le altre caratteristiche) in modo che la codifica sia più chiara e più facile da costruire e comprendere. Tuttavia, questa funzione non è sempre pronta all'uso. Nel tuo esempio, OO ti ha permesso di nascondere alcuni dettagli da me fornendo un metodo per gestire gli elementi in una raccolta e potrebbe persino persistere usando il metodo "AddItem". Spendere sforzi per nascondere la complessità può risultare in una struttura facile da usare e riutilizzabile che semplifica la vita. Ad esempio, molte implementazioni ORM consentono di comunicare con i database senza che il programmatore abbia scritto i dettagli SQL. Questo è davvero potente e lo rende più semplice sullo sviluppatore.

I modelli a cui fai riferimento sono proprio questo. Dovrebbero semplificarti la vita. Ma spetta a te adottarli e regolarli. Il fatto che sia necessario più lavoro è solo perché ottieni più benefici. È come pagare di più per una Ferrari. Se vuoi gli extra che paghi per loro. Pertanto, se si decide di creare una soluzione scalabile N-Tier che può essere eseguita su diversi server e diversi database back-end, è previsto un costo. Se la tua applicazione non richiede questa complessità, ignora i pezzi extra e ricollega alla soluzione più semplice che copre le tue necessità (KISS & YAGNI).

Quindi, per concludere, non penso che l'OOP come concetto stesso stia diventando più complesso, noi, gli utenti di OOP abbiamo la possibilità di usarlo in modi diversi, e questa è una buona cosa.

    
risposta data 10.06.2012 - 16:53
fonte
3

Risposta breve : Sì, perché ti occupi di problemi più difficili.

Risposta lunga (strongmente sbilanciata) : per me i modelli di progettazione di solito indicano che alcuni paradigmi hanno problemi in un'area specifica. I modelli OOP trattano problemi di OOP (a livello inferiore i modelli Java affrontano problemi di Java), i modelli FP riguardano problemi di FP ecc.

Durante la programmazione potresti avere priorità diverse. Si consiglia di avere un programma corretto, si consiglia di ridurre il time-to-market, il programma più veloce possibile, la manutenzione a lungo termine o la manutenibilità istantanea con una nuova assunzione. A seconda della fittazza in cui ci si trova, si avrà una grande differenza: se si sta programmando il controller di una centrale elettrica, si desidera eseguire correttamente la prima volta e non correggere ogni volta ("Il crollo si verifica ogni volta che si preme Ctrl + alt + Del ? "). Se si è in HPC, la logica può essere relativamente semplice, ma si desidera eseguirla il più velocemente possibile ecc. Ecc. Inoltre alcuni paradigmi si adattano meglio a determinati problemi (ad esempio programmazione di intelligenza artificiale e logica, dati e database relazionali).

OOP è in qualche modo "troppo buono" in casi semplici ed è una storia di "modellizzazione del vero vivere". Ad esempio, nel primo libro su OOP ho letto che c'erano le classi Person , Employee e Manager con is-a relazione. Fin qui tutto bene, ma cosa succede se il dipendente è promosso a manager?

D'altra parte altri paradigmi hanno lezioni più difficili per la prima volta - ad esempio FP con variabili immutabili (la cosa divertente è che le persone che hanno esperienza con la programmazione spesso trovano più difficile imparare rispetto a quelli per cui questa è la prima lingua) - tuttavia alla fine non sono più difficili di OOP. Testare funzioni pure è banale e in Haskell / Scala / ... hai strumenti che generano test per te.

PS. Sì, la risposta è distorta contro l'OOP e ammetto che in qualche modo è "in reazione" a OOP. OOP ha i suoi usi ma a mio parere non è l'unica soluzione definitiva.

PPS. Sì, usa schemi di progettazione - rendono la programmazione OOP in definitiva più semplice.

PPP. Ho usato OOP come sinonimo di programmazione imperativa OOP.

    
risposta data 10.06.2012 - 20:34
fonte
2

Penso che sia più un caso di documenti ed esempi che diventano più realistici.

I primi libri OOP (in particolare i primi libri in Java) presentavano una visione assurdamente semplificata della programmazione delle applicazioni. Il programma "Addebitare un conto bancario con un programma Java a 10 linee" è sempre stato particolarmente fastidioso poiché ho visto esempi di vita reale di questa semplice operazione eseguita su 6000 righe di codice COBOL (e il tentativo di sostituzione di Java in esecuzione su 3500 linee prima di essere abbandonato come irrealizzabile!).

Per fortuna i libri di OO ora tendono a riconoscere le complessità della vita reale e forniscono esempi utili su come affrontarli.

Ma se vuoi vedere come eseguire un conto bancario in solo 15 righe di codice programmazione funzionale è il tuo uomo

    
risposta data 11.06.2012 - 06:53
fonte