Relazione tra orientamento dell'oggetto e algoritmi


9

Mentre leggo alcuni manuali di algoritmi, sono pieni di procedure intelligenti per alcuni problemi (ordinamento, percorso più breve) o alcuni metodi generali (algoritmi ricorsivi, divisione e conquista, programmazione dinamica ...). Ho trovato poche tracce di programmazione orientata agli oggetti lì; (Perché sono più orientati alla procedura?).

Poi stavo pensando:

  • Qual è la relazione tra algoritmi e OOP? Sono due argomenti indipendenti?
  • Ci sono alcuni problemi che possono essere presentati e risolti solo da OOP?
  • In che modo OOP può aiutare gli algoritmi? O in quale direzione può influenzarlo?


@DocBrown Grazie, è stato molto utile, tuttavia qui possiamo considerare alcuni concetti intorno all'OO come eredità, polimorfismo ...
Ahmad

1
"Perché il manuale degli algoritmi è più orientato alle procedure?" Java è anche orientato alle procedure. Java è un linguaggio procedurale orientato agli oggetti.
Pieter B,


1
@gnat Ho modificato la mia domanda, non so se quella spiegazione fosse necessaria o buona o no. Tuttavia, ammetto che la domanda posta da Doc Brown possiede più risposte legate alle mie preoccupazioni.
Ahmad,

Risposte:


10

Innanzitutto, definiamo cosa intendiamo per OOP. Per OOP intendo principalmente:

  • Incapsulamento e occultamento dei dettagli in classe.
  • Polimorfismo del comportamento attraverso ereditarietà e metodi virtuali.

Ora, per rispondere alla tua domanda:

Qual è la relazione tra algoritmi e OOP? Sono due argomenti indipendenti?

Sì.

Ci sono alcuni problemi che solo OOP può presentare e risolvere?

No. OOP primario offre praticità e capacità di ragionare sul codice per il programmatore. Non aumenta il tuo potere espressivo.

In che modo OOP può aiutare gli algoritmi? O in quale direzione può influenzarlo?

Come ho detto sopra. Entrambi i punti che ho descritto OOP si applicano qui. Essere in grado di nascondere i dettagli degli algoritmi e delle loro strutture di dati può aiutare a ragionare su tutto. Molti algoritmi contengono dettagli con i quali non si desidera che l'utente di quell'algoritmo si scherzi. Nascondere questi dettagli aiuta molto.

Anche la capacità di avere un comportamento polimorfico è grande. Listè definito come essere in grado di aggiungere / rimuovere / cancellare gli elementi in qualsiasi punto della raccolta. Ma può essere implementato come array ridimensionabile, doppio collegamento o singolo collegamento, ecc. Avere un'unica API per più implementazioni può aiutare a riutilizzare.

Perché il manuale degli algoritmi è più orientato alle procedure?

Come ho detto, OOP non è necessario per implementare un algoritmo. Inoltre, molti algoritmi sono vecchi e creati quando OOP non era ancora molto diffuso. Quindi potrebbe anche essere una cosa storica.


1
Nonostante l'età dei testi, probabilmente non vorrai confondere l'acqua di un algoritmo con OOP, solo perché è moderno.
Gusdor,

15

Algoritmi e OOP sono due termini disparati, che hanno solo in comune, che sono CS- term. Semplicemente - Un algoritmo è come una ricetta di cucina : per fare x hai bisogno dei seguenti ingredienti e fare il passo 1,2,3,4,5,6 ... quindi hai preparato il tuo pasto.

Detto questo, sembra che gli algortihms possano essere descritti in modo procedurale . Procedurale non significa altro che: prima fai x e poi fai y .

Un problema comune è: »Come ordinare un set di x ?«. Una soluzione di facile comprensione è bubble-sort:

  1. Scorri sull'insieme dall'ultimo elemento finché non hai raggiunto il primo elemento e durante l'iterazione
  2. Inizia una seconda iterazione dall'inizio fino all'elemento corrente della prima iterazione e
  3. Confronta l'elemento corrente di (2) con il suo successore
  4. Se maggiore, scambia posizioni

Questa è la descrizione algoritmica / verbale bubblesortdell'algoritmo.

Ecco che arriva un'implementazione procedurale / pseudocodice

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

È stato facile.

Come si relaziona a OOP ? È possibile utilizzare questo algoritmo per trattare le raccolte (un oggetto stesso) di oggetti :

Esempio in Javascript (sebbene non sia pulito OO-Lingo , ma con quasi nessuna piastra di cottura e facile da capire)

objects =[{"name":"Peter"}, {"name":"Paul"}, {"name":"Mary"}]

compareObjects=function(x,y){ return x.name>y.name };

sorted = objects.sort(compareObjects)

console.log(sorted)

Abbiamo a) una raccolta objects, b) un metodo comune a questa raccolta sortche contiene / estrae l'algoritmo di ordinamento ec) i nostri oggetti Pietro , Paolo e Maria . Le specifiche per l'ordinamento sono disponibili qui .

Qual è la relazione tra algoritmi e OOP? Sono due argomenti indipendenti?

Da quanto detto, dovrebbe essere chiaro, la risposta dovrebbe essere: sì, sono indipendenti.

In che modo OOP può aiutare gli algoritmi? O in quale direzione può influenzarlo?

OOP è solo uno stile di programmazione. Non può aiutare in nessun tipo. Altrimenti un algoritmo potrebbe essere implementato in un linguaggio OO per fare qualcosa agli oggetti (come mostrato)

Ci sono alcuni problemi che solo OOP può presentare e risolvere?

Non riesco a pensarne uno (ma ciò non significa che sia impossibile). Ma se lo guardi al contrario: OOP è utile, se vuoi modellare alcuni problemi e risolverli con un algoritmo appropriato. Diciamo che avete un record di friendsli potrebbe modellare come objectscon propertiese se si desidera una listdi friends ordinato in qualsiasi modo, è possibile utilizzare l'esempio di codice di cui sopra per fare esattamente questo.

Perché il manuale degli algoritmi è più orientato alle procedure?

Come detto: è più naturale , poiché la procedura è il carattere degli algoritmi.


7
Questa risposta presuppone che gli algoritmi siano naturalmente procedurali. Certamente alcuni di loro lo sono, ma esiste qualcosa come gli algoritmi funzionali. Il motivo per cui i libri sugli algoritmi sono procedurali probabilmente ha più a che fare con il fatto che sono focalizzati sulle prestazioni, e quindi spetta al lettore preoccuparsi di far rispettare le astrazioni e perché i linguaggi imperativi sono più popolari dei linguaggi funzionali.
Doval,

Penso che non sia del tutto esatto. Quando parli di linguaggi di programmazione funzionale , stai parlando dell'implementazione , non dell'algoritmo stesso. Prendiamo ad esempio il quicksort di Haskell wiki.haskell.org/Introduction#Quicksort_in_Haskell Siamo entrambi d'accordo sul fatto che si tratta di un'implementazione funzionale di quicksort-algortihm. Ma se descrivi ciò che viene fatto, devi eseguire il fallback in una modalità descrittiva prodecurale . E da questa descrizione, è possibile implementare un'implementazione procedurale.
Thomas Junk,

1
@ThomasJunk Lei non deve ripiegare a una modalità procedurale della descrizione, perché un'implementazione funzionale dice ciò che le cose sono , non una sequenza di passi. Come darai una descrizione sequenziale per un calcolo puro e pigro? Non si conosce in anticipo la quantità di espressione che verrà valutata, né in quale ordine verranno calcolate le sue sottoespressioni.
Doval,

2
Purtroppo non ho una laurea in CS, quindi non ho un ampio set di competenze per provare quanto segue: ma penso che ogni algoritmo possa essere descritto in un modo o nell'altro, quindi non esiste un vero algoritmo funzionale puro. Non è ciò che significa la completezza del tour di conseguenza?
Thomas Junk,

2
@Doval bene dal momento che lo stesso Turing ha dimostrato che il calcolo lambda e le macchine di Turing sono equivalenti, quindi è ovvio tutto ciò che puoi affermare in modo funzionale, puoi farlo in modo imperativo. Inoltre è banale convertire il calcolo pigro in forma imperativa - il compilatore di Haskell lo fa sempre ... Alla fine è solo una questione di preferenza. A volte funzionale è più adatto, a volte imperativo, altre volte logico è il migliore ...
AK_

5

hai un problema.

Il modello di dominio aziendale descrive il tuo problema e i concetti del dominio problematico di cui ti occuperai.

Gli algoritmi descrivono il modo in cui risolverai i tuoi problemi, concettualmente; come sarà la tua implementazione; e come affrontare il problema dopo averlo tradotto in termini di "Informatica".

Il paradigma di programmazione, che sia OOP, funzionale, logico, procedurale o anche non strutturato, descrive come strutturerai la tua soluzione, quale forma prenderà, quali concetti di "Ingegneria del software" utilizzerai e quali " Teoria del linguaggio di programmazione "concetti che utilizzerai.

Per dirla più semplicemente, gli algoritmi descrivono in generale la tua soluzione al problema ("Questo è quello che farò"). Mentre il paradigma di programmazione si occupa della tua effettiva implementazione ("Ecco come lo farò").


Si noti che in un modo forse imperfetto, i linguaggi dichiarativi mirano a ridurre o eliminare il passaggio "how". Il loro obiettivo è che tu dica semplicemente "questo è quello che voglio" (ad esempio, scrivendo equazioni di alto livello). Pensa a una tipica query SQL: molto poco è "algoritmica"; dite semplicemente al database cosa volete e dipende da come gestisce la vostra richiesta (entro certi limiti, ovviamente).
Andres F.

4

Algoritmi = racconta la storia " Come " (ovvero come manipolare i dati di input usando le strutture di dati in tempo per produrre i risultati desiderati)

OOP = una " metodologia " facilitata dai linguaggi OO per scrivere programmi (= algoritmi + strutture di dati) che ti dia sicurezza e astrazione della memoria

OOP è solo un paradigma di implementazione di algoritmi.

Buona analogia : i film

Puoi registrare scene impiegando uno stuntman o meno. La sceneggiatura (algoritmo) non cambia. Le persone non dovrebbero vedere alcuna differenza nel risultato finale.

EDIT: potresti provare un MOOC di buona qualità: https://www.coursera.org/course/algs4partI che collega gli argomenti discussi (in particolare l'approccio OOP) e dà l'essenza di ciò che chiedi qui.


Mi è davvero piaciuta la tua analogia cinematografica. Prenderò in prestito quello in futuro.
Marc LaFleur,

2

Alexander Stepanov è il creatore originale della libreria di modelli standard C ++ (STL), che è la libreria di algoritmi di base per C ++. C ++ è un linguaggio multi-paradigma che include funzionalità "orientate agli oggetti", ma Alexander Stepanov ha questo da dire sull'orientamento degli oggetti:

http://www.stlport.org/resources/StepanovUSA.html

STL non è orientato agli oggetti. Penso che l'orientamento agli oggetti sia quasi una bufala come l'intelligenza artificiale. Devo ancora vedere un pezzo interessante di codice che proviene da queste persone OO.

Trovo che OOP tecnicamente non sia corretto. Tenta di scomporre il mondo in termini di interfacce che variano su un singolo tipo. Per affrontare i problemi reali sono necessarie algebre multisorted: famiglie di interfacce che si estendono su più tipi. Trovo OOP filosoficamente insoddisfatto. Afferma che tutto è un oggetto. Anche se è vero, non è molto interessante - dire che tutto è un oggetto non dice nulla. Trovo OOP metodologicamente sbagliato. Si inizia con le classi. È come se i matematici iniziassero con gli assiomi. Non inizi con gli assiomi, inizi con le prove. Solo quando hai trovato un mucchio di prove correlate, puoi elaborare assiomi. Finisci con gli assiomi. La stessa cosa vale per la programmazione: devi iniziare con algoritmi interessanti. Solo quando li capisci bene,

Ho trascorso anni cercando di trovare un qualche vantaggio per l'ereditarietà e i virtuali, prima di capire perché quel meccanismo era fondamentalmente imperfetto e non doveva essere usato.

Stepanov ha espresso la sua libreria di algoritmi non con Oggetti, ma con Iteratori generici .


Beh, ha torto ... principalmente perché l'STL è molto orientato agli oggetti ... Orientato agli oggetti in modo più moderno dal termine ...
AK_

1
@AK_ - Non penso che abbia torto. STL non è nemmeno approssimativamente OO in alcun senso del termine. È possibile tradurre l'STL direttamente in un linguaggio non OO con polimorfismo parametrico (ad es. Haskell o SML) senza la necessità di modificarlo in modo sostanziale.
Jules il

2

Gli algoritmi descrivono cosa dovrebbe fare il computer. La struttura descrive come è strutturato l'algoritmo [nel codice sorgente]. OOP è uno stile di programmazione che sfrutta determinate strutture "orientate agli oggetti".

I libri degli algoritmi spesso evitano OOP perché sono focalizzati sull'algoritmo, non sulla struttura. Frammenti di codice che dipendono fortemente dalla struttura tendono ad essere scarsi esempi da inserire in un libro di algoritmi. Allo stesso modo, i libri di OOP spesso evitano gli algoritmi perché ingombrano la storia. Il punto di forza di OOP è la sua fluidità e il suo aggancio a un algoritmo lo rende più rigido. Si tratta più del focus del libro che di ogni altra cosa.

Nel codice della vita reale, userete entrambi fianco a fianco. Non puoi risolvere i problemi del computer senza algoritmi, per definizione, e troverai difficile scrivere buoni algoritmi senza struttura (OOP o altro).

Come esempio di dove si confondono, prendi la Programmazione dinamica. In un libro di algoritmi, descriveresti come prendere un set di dati omogeneo in un array e usare la Programmazione dinamica per arrivare a una soluzione. In un libro OOP, potresti imbatterti in una struttura come Visitatore, che è un modo per eseguire algoritmi arbitrari su una serie di oggetti eterogenei. L'esempio del libro DP potrebbe essere considerato come un visitatore molto semplice che opera su oggetti in un ordine generalmente dal basso verso l'alto. Il modello Visitatore potrebbe essere considerato lo scheletro di un problema DP, ma manca la carne e le patate. In realtà, scoprirai che spesso hai bisogno di entrambi insieme: usi il modello di Visitatore per gestire l'eterogeneità nel tuo set di dati (DP non va bene in questo) e usi DP all'interno della struttura di Visitatore per organizzare l'algoritmo per ridurre al minimo il runtime (Visitatore doesn'

Vediamo anche algoritmi che operano al di sopra dei modelli di progettazione. È più difficile esprimere esempi in un piccolo spazio, ma una volta che hai una struttura, inizi a voler manipolare quella struttura e usi gli algoritmi per farlo.

Ci sono alcuni problemi che possono essere presentati e risolti solo da OOP?

Questa è una domanda più difficile a cui rispondere di quanto pensi. Per il primo ordine, non esiste alcun motivo computazionale per cui è necessario OOP per risolvere qualsiasi problema. La semplice prova è che ogni programma OOP viene compilato fino all'assemblaggio, che è un linguaggio decisamente non-OOP.

Tuttavia, nel più grande schema delle cose, la risposta inizia a timida verso sì. Raramente sono limitati semplicemente dalle metodologie di calcolo. Il più delle volte ci sono cose come le esigenze aziendali e le capacità degli sviluppatori che incidono sull'equazione. Molte applicazioni oggi non potrebbero essere scritte senza OOP, non perché OOP è in qualche modo fondamentale per il compito, ma perché la struttura fornita da OOP era essenziale per mantenere il progetto sulla buona strada e sul budget.

Ciò non significa che non abbandoneremo mai OOP in futuro per qualche nuova struttura divertente. Dice semplicemente che è uno degli strumenti più efficaci nella nostra cassetta degli attrezzi per una frazione sorprendentemente ampia di attività di programmazione oggi disponibili. I problemi futuri potrebbero portarci ad affrontare lo sviluppo usando strutture diverse. Per uno, mi aspetto che le reti neurali richiedano un approccio di sviluppo molto diverso, che può o meno rivelarsi "orientato agli oggetti".

Non vedo OOP scomparire nel prossimo futuro a causa del modo in cui i progettisti di algoritmi pensano. Ad oggi, il solito schema è che qualcuno progetta un algoritmo che non sfrutta OOP. La comunità OOP si rende conto che l'algoritmo non si adatta davvero alla struttura OOP, e davvero non è necessario, quindi avvolgono l'intero algoritmo in una struttura OOP e iniziano a usarlo. Prendere in considerazione boost::shared_ptr. Gli algoritmi di conteggio dei riferimenti che si shared_ptrtrovano all'interno non sono molto compatibili con OOP. Tuttavia, il modello non è diventato popolare fino a quando non è stato shared_ptrcreato un wrapper OOP attorno ad esso che ha esposto le capacità degli algoritmi in un formato strutturato OOP. Ora, è così popolare che è diventato l'ultima specifica per C ++, C ++ 11.

Perché questo ha tanto successo? Gli algoritmi sono ottimi per risolvere i problemi, ma spesso richiedono un investimento iniziale sostanziale nella ricerca per capire come usarli. Lo sviluppo orientato agli oggetti è molto efficace nel confezionare tali algoritmi e fornire un'interfaccia che richiede un investimento iniziale inferiore per l'apprendimento.


1

Oltre alle grandi risposte, citerò un'ulteriore comunanza concettuale tra OOP e algoritmi.

Sia OOP che Algorithms sottolineano fortemente l'uso di precondizioni e postcondizioni per garantire la correttezza del codice.

In generale, questa è una pratica standard in tutte le aree dell'informatica; tuttavia, questo principio guida determina un percorso evolutivo in OOP che rende reciprocamente vantaggioso implementare algoritmi in ambiente OOP.

In OOP, un gruppo di oggetti in grado di soddisfare lo stesso contratto (precondizioni e postcondizioni) può essere creato per implementare un'interfaccia. L'utente di tale interfaccia non avrà bisogno di sapere quale implementazione viene utilizzata nell'oggetto sottostante, tranne in alcune rare situazioni (in cui si verifica un'astrazione che perde).

Un algoritmo è un'implementazione dei passaggi utilizzati per eseguire un calcolo, uno che prenderà il presupposto e produrrà il postcondizionato.

Pertanto, si può prendere in prestito l'idea di astrazione in termini di precondizioni e postcondizioni e applicarla agli algoritmi. Scoprirai che a volte algoritmi complicati possono essere scomposti in passaggi più piccoli e questi passaggi più piccoli possono consentire strategie di implementazione diverse purché siano soddisfatte le stesse condizioni preliminari e postcondizioni.

Implementando algoritmi in OOP, si possono rendere intercambiabili questi piccoli passi.

Infine, tieni presente che FP e OOP non si escludono a vicenda. Tutto quanto sopra descritto può essere ugualmente applicabile anche a FP.


Grazie per il punto! Come hai detto se l'algoritmo è solo alcuni passaggi, OOP può aiutarci a fornire passaggi più astratti. Hai indicato "l'implementazione di algoritmi in OOP", ho modificato la mia domanda per chiedere è sempre utile?
Ahmad,

1
stai confondendo OOP con "Design by Contract". È molto utile senza OOP, e la maggior parte dei linguaggi OOP (C #, Java) non fornisce un supporto reale (supportano interfacce semplici, non condizioni pre / post)
AK_6

1
@AK_ Accetto che Design by Contract sia il nome corretto per il carattere comune descritto nella mia risposta. Quello che sto affermando è che OOP come paradigma del design abbraccia fortemente Design by Contract - basta leggere qualsiasi libro di testo OOP. La mia risposta originale menziona anche che questa comunanza non è esclusiva di OOP.
rwong

-1
What is the relation between algorithms and OOP? Are they two independent topics?

Gli algoritmi riguardano come risolvere un problema (come generare output dall'input dato), OOP riguarda come formulare o esprimere la nostra soluzione (i passaggi dell'algoritmo).

Un algoritmo può essere descritto in linguaggio naturale o in linguaggio assembly, ma i concetti che abbiamo in un linguaggio naturale ci aiutano a scriverlo e comprenderlo meglio. Ad esempio l'algoritmo per bubble-sort potrebbe essere:

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

Per nascondere i dettagli swape metterli in relazione con Auna sintassi e una funzionalità OOP utilizzate, OO rende l'algoritmo più vicino al nostro linguaggio naturale e alla nostra comprensione.

Are there some problems which can only be presented and solved by OOP?

No, se si considera che qualsiasi programma (o algoritmo) su un computer verrà tradotto in una serie di istruzioni eseguite su CPU ( Turing Machine ) e se consideriamo queste istruzioni come l'algoritmo finale che risolve il problema su un computer , allora OOP non posso fare altro. Lo rende solo più vicino alla comprensione e al ragionamento umani. È un modo per impacchettare le nostre procedure e strutture di dati.

How OOP can help algorithms? Or in which direction it can affect it?

Può essere utile affermare o formulare un algoritmo più semplice o più comprensibile. Può nascondere i dettagli e fornire una visione d'insieme della soluzione.

In teoria, l'algoritmo è il primo e lo implementa il secondo . Ma in realtà, non possiamo essere sicuri che il nostro algoritmo funzioni come previsto fino a quando non lo tracciamo o generiamo l'output previsto. I computer ci aiutano a farlo, ma non ti aspetti di scriverlo in linguaggio macchina (assembly).

A questo proposito, OOP facilita l'implementazione, il test e il perfezionamento del nostro algoritmo su computer e lo scrive per un computer in una lingua vicina al nostro linguaggio naturale.

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.