Quando utilizziamo effettivamente la programmazione orientata agli oggetti? [chiuso]


35

Sto scrivendo un programma in Python, che sostanzialmente manipola le stringhe, e mi chiedevo se avrei dovuto farlo usando i principi OOP o meno. Il cliente ha dirmi che non si preoccupa per il codice, lui vuole solo la cosa fatta .

So che il codice orientato agli oggetti non è per definizione più pulito, e al contrario il codice non OO non è per definizione scadente. La domanda che sto ponendo potrebbe essere più o meno basata sull'opinione, ma potrebbero esserci alcune regole di cui non sono a conoscenza.

Altre informazioni su cosa fare:

  • analizzare un .csvfile ed elaborare i dati in base a un file di configurazione (le colonne possono essere diverse, ad esempio nel numero di colonne o nei dati in loro possesso)
  • utilizzare i dati elaborati sopra per creare nuovi dati formattati personalizzati (o più file basati su alcuni dei valori sopra)
  • usa gli ultimi dati formattati per creare un file XML.
  • dividere il file XML in più XMLs in base al loro contenuto
  • l'applicazione dovrebbe essere basata sulla CLI
  • ci sono ovviamente altre cose come: la registrazione di alcuni eventi, l'analisi degli argomenti della CLI e così via.

Ora, questa non è affatto un'applicazione grande / difficile, ed è anche quasi finita, ma durante l'intero processo di sviluppo continuavo a chiedermi se questo dovesse essere fatto usando OOP o no.

Quindi, la mia domanda sarebbe: come fate, sapete / decidete quando usare OOP in un'applicazione?


12
Ri, "Al cliente ... non interessa il codice, vuole solo fare la cosa." OK, allora fai la cosa. Ma quanto è complessa questa cosa? Quanto bene capisci davvero i requisiti? Con che probabilità il cliente ti chiederà in seguito di cambiare la cosa? A volte è sufficiente un trucco rapido e sporco, ma più tempo ed energia investirai in esso, più è probabile che un approccio strutturato alla risoluzione del problema (ad esempio, la progettazione OO) ti sia di beneficio.
Solomon Slow,

5
Non utilizzare "EDIT" o altri moniker simili nei tuoi post. Ogni post di Stack Exchange ha una cronologia delle modifiche dettagliata che chiunque può rivedere. Informazioni come "Non ho chiesto cosa fosse OOP" sono comunque più appropriate in un commento, non alla tua domanda.
Robert Harvey,

@RobertHarvey ok, capito. Lo farò la prossima volta.
Grajdeanu Alex.

Risposte:


60

Python è un linguaggio multi-paradigma che significa che puoi scegliere il paradigma più appropriato per l'attività. Alcuni linguaggi come Java sono OO a singolo paradigma, il che significa che otterrai mal di testa se provi a utilizzare qualsiasi altro paradigma. I manifesti che dicono "usa sempre OO" probabilmente provengono da un background in una tale lingua. Ma per fortuna hai una scelta!

Prendo atto che il tuo programma è un'app CLI che legge alcuni input (file csv e config) e produce alcuni output (file xml), ma non è interattivo e quindi non ha una GUI o API con stato. Tale programma è naturalmente espresso in funzione da input a output, che delegano ad altre funzioni per attività secondarie.

OO d'altra parte riguarda l'incapsulamento dello stato mutabile ed è quindi più appropriato per applicazioni interattive, GUI e API che espongono lo stato mutabile. Non è un caso che OO sia stato sviluppato parallelamente alle prime GUI.

OO ha un altro vantaggio in quanto il polimorfismo consente un'architettura più liberamente accoppiata, in cui diverse implementazioni della stessa interfaccia possono essere facilmente sostituite. In combinazione con l'iniezione delle dipendenze, ciò può consentire il caricamento di dipendenze e altre cose interessanti basate sulla configurazione. Questo è principalmente appropriato per applicazioni molto grandi. Per un programma delle dimensioni di ciò che descrivi, sarebbe eccessivamente eccessivo senza alcun vantaggio apparente.

Oltre alle funzioni che leggono e scrivono i file, la maggior parte della logica può essere scritta come funzioni libere da effetti collaterali che accettano input e restituiscono altri output. Questo è estremamente facile da testare, molto più semplice rispetto al test di unità OO in cui è necessario deridere dipendenze e quant'altro.

In conclusione: suggerisco un sacco di funzioni suddivise in moduli per l'organizzazione, ma senza oggetti.


8
Finalmente una risposta equilibrata che non canta solo le lodi di OOP :-)
cmaster

1
Questo è il tipo di risposta che mi aspettavo. Potresti espandere un po 'la tua risposta? Sembra fantastico finora.
Grajdeanu Alex.

3
@ Dex'ter: Than you. Che tipo di informazioni aggiuntive cerchi?
JacquesB,

3
Aggiungerei a questo che la programmazione funzionale potrebbe essere un paradigma su cui leggere.
Andrew dice Reinstate Monica il

1
@Bergi: Sì, questo è il vantaggio di un linguaggio multi-paradigma. È possibile utilizzare le librerie OO senza dover scrivere il proprio programma in stile OO.
JacquesB,

15

Considera un pulsante in una GUI. Ha stato (è dimensione, colore, posizione, etichetta ecc.). Le cose possono succedere (si fa clic, è necessario ridisegnare ecc.). In tali situazioni, modellarlo come un oggetto ha senso. Come oggetto, può contenere il suo stato, un insieme di azioni che possono essere eseguite su di esso (metodi) e può notificare ad altre parti dell'applicazione che le cose sono successe con l'attivazione di eventi.

OOP è uno strumento eccezionale per la gestione delle GUI e altre situazioni in cui parti del sistema hanno uno stato volatile.

Altre situazioni, come quella che descrivi, in cui i dati vengono letti da una fonte, elaborati e scritti in una destinazione sono gestiti bene da un approccio diverso: la programmazione dichiarativa (o funzione). Il codice dichiarativo per l'elaborazione dei dati tende ad essere sia più facile da leggere sia più breve delle soluzioni OOP.

Proprio come un martello e una sega sono entrambi potenti strumenti se usati correttamente, così come lo sono anche le tecniche di programmazione orientate agli oggetti e dichiarative. Probabilmente potresti martellare un chiodo in un pezzo di legno con la maniglia di una sega. Allo stesso modo, puoi rompere un pezzo di legno a metà con un martello. Allo stesso modo, è possibile creare una GUI con solo funzioni ed elaborare i dati con oggetti. Tuttavia, quando gli strumenti vengono utilizzati correttamente, i risultati sono più puliti e più semplici.

La regola generale che uso è che se ho molto stato o ho bisogno dell'interazione dell'utente, uso gli oggetti; altrimenti utilizzo le funzioni (ordine puro e superiore, ove possibile).


6

La programmazione orientata agli oggetti aggiunge quattro nuovi strumenti al tuo arsenale:

  1. incapsulamento
  2. Astrazione
  3. Eredità
  4. Polimorfismo

Utilizzerai OOP nella tua applicazione quando è diventata abbastanza grande e abbastanza complessa da beneficiare di questi strumenti.


18
Astrazione e polimorfismo sono strumenti forniti da molti "orientamenti" della programmazione. OOP offre in realtà una forma più debole di incapsulamento rispetto ad altri approcci perché l'ereditarietà incoraggia i progetti di astrazione che perde. L'unica cosa che OOP aggiunge davvero al toolkit è l'eredità, che è ampiamente considerata una cosa negativa.
David Arno,

4
@DavidArno: In pratica stai dicendo "Non usare mai OOP".
Robert Harvey,

6
Questo è alla base di una dura giornata di lavoro guardando il codice di altre persone, un'implementazione procedurale diretta di un programma è spesso migliore di un'implementazione con una cattiva comprensione del design di OO. L'architettura OO può essere molto potente ma dovrebbe essere usata come una spezia in cucina, con conoscenze specialistiche e la giusta quantità. L'uso improprio del design OO è comune quanto la richiesta di ketchup in un cattivo ristorante.
Phill,

6
Nessuno dei quattro strumenti (incapsulamento, astrazione, ereditarietà, polimorfismo) è specifico di OOP. Forse dovresti spiegare come OOP è diverso dagli altri paradigmi scritti su queste dimensioni.
Giorgio,

4
@gardenhead il tuo strano senso di superiorità non sta facendo nulla per la tua posizione. Forse dovresti fare una domanda intitolata "Perché le lingue più impiegabili sono spesso OO?" Meglio ancora, Ctrl + F e digitare "GUI".
Gusdor,

1

Questa domanda mi sembra un po 'confusa. Se lo scrivi in ​​Python, utilizzerai sicuramente degli oggetti. Quando si apre un file, restituisce un oggetto. Quando si ottiene risultato, restituisce un oggetto iteratore. Ogni funzione che crei è un oggetto. Mettere in discussione il valore di OO nelle applicazioni Python sembra a dir poco strano.

Sulla base dei commenti qui, sì, Python supporta paradigmi funzionali ma è principalmente basato sugli oggetti. Il linguaggio stesso e le librerie integrate sono orientati attorno agli oggetti. Sì, supporta lambda (così come Java e qualsiasi altro numero di lingue tipicamente descritto come OO) ma è intenzionalmente semplicistico rispetto a un vero linguaggio funzionale.

Forse queste distinzioni tra design OO e design funzionale stanno diventando obsolete. Se creo accetta una funzione polimorfica su un oggetto progettato OO * e passo un puntatore a quella funzione su un oggetto come parametro per una funzione in stile funzionale *, è OO o è funzionale? Penso che sia sia un approccio davvero efficace per risolvere i problemi.

Penso che la vera domanda sia "quando dovresti iniziare a progettare le tue classi piuttosto che creare un modulo con funzioni?" Penso che la risposta giusta sia: quando aiuta a semplificare la soluzione. Darei la stessa risposta di base per qualsiasi linguaggio orientato agli oggetti.

* la ridondanza è intenzionale: non voglio essere accusato qui di presumere che gli oggetti siano OO o che le funzioni siano funzionali.


5
sì, gli oggetti non sono uguali a OOP. c'è una differenza tra avere un oggetto e strutturare la tua architettura attorno agli oggetti e alle loro interazioni. un po 'come se crei una funzione che non significa che stai facendo una programmazione funzionale.
Sara

potresti facilmente considerare un oggetto Python / JavaScript come un Record, che è abbastanza funzionale. I linguaggi funzionali hanno oggetti. La chiave è nella seconda parola: orientata. I linguaggi OOP sono completamente orientati all'utilizzo degli oggetti, mentre alcuni altri linguaggi li sembrano semplicemente un'altra parte della casella degli strumenti.
Dan Pantry,

0

Una delle cose più importanti della programmazione orientata agli oggetti è che invece di ragionare sul flusso del programma, inizi a ragionare sullo stato.

Molte volte vedo l'oggetto, vedo i metodi, ma vedo anche che il pensiero guida dietro il codice è flusso anziché stato.

E una volta che ragionate sullo stato, è facile costruire un buon codice OOP perché non appena il codice diventa troppo complesso, notate che non potete più ragionare sul vostro stato e sapete che dovete rifattorizzare.

Considera il tuo esempio: vuoi analizzare un file CSV. Da dove viene: un file su disco. Lo carichi, lo metti in memoria e lo analizzi. Ora arriva il tuo cliente: ehi, voglio anche analizzare i file dal web. Quindi sei felice perché hai creato una bella interfaccia per caricare il tuo file e devi solo rendere il codice che lo recupera dal web e il resto del tuo programma rimane esattamente lo stesso.

E la cosa bella è: puoi provarlo.


3
Il tuo esempio con la lettura di un file dal disco rispetto alla lettura di un file dal web può anche essere implementato con diverse funzioni. Non hai bisogno di OO per quello.
JacquesB,

0

In parole povere:

  • Puoi utilizzare OOP o non-OOP in qualsiasi tipo di progetto desideri.
  • OOP non è la panacea ma aiuta a gestire la complessità.
  • Va oltre la modularità, riguarda la compartimentazione. Pensa ai diversi compartimenti di una nave per mantenere la galleggiabilità se lo scafo è danneggiato.
  • OOP è un modo di gestire le dipendenze, quindi i bug possono essere più facili da rintracciare poiché esiste solo un insieme definito di modi in cui i diversi componenti di un programma possono comunicare quali altri.
  • In un programma ci sono molte cose che funzionano: variabili, costanti, metodi, file, parametri, funzioni, moduli, ecc. Possono interagire tra loro in modi a volte imprevedibili. OOP è un insieme di principi che riducono il numero di modi in cui le cose possono interagire tra loro. Non sei obbligato a usare OOP per farlo, ma aiuta.

Detto questo, ci sono altri fattori da tenere in considerazione:

  • I tuoi programmatori sono esperti in OOP / OOD?
  • I tuoi programmatori sono abili in un linguaggio OOP?
  • Pensi che il software diventerà complesso nel tempo?
  • Intendi ridimensionare o riutilizzare il codice in futuro?
  • Pensi che il tuo "design" possa diventare una risorsa? cioè sarai in grado di sfruttarlo per crescere o come base per progetti futuri?

Non fraintendetemi: potete ottenere tutto ciò senza usare OOP ma con OOP sarà più facile.

Ma...

Se il tuo team non è esperto in OOP / OOD e non ha esperienza in quell'area, vai con le risorse che hai.


-2

Quindi, la mia domanda sarebbe: come fate, sapete / decidete quando usare OOP in un'applicazione?

Usalo sempre. Una volta che sei abituato a usarlo, lo userai per tutto. È un ottimo modo per garantire una buona astrazione tra le capacità e il loro utilizzo, il che rappresenta un vantaggio significativo per la manutenzione. Lo usiamo, per esempio, per

  • piccoli oggetti di struttura di dati perché sono spesso polimorfici, ad esempio una struttura di dati intermedia dopo l'analisi di qualcosa ha spesso più entità piccole, che hanno un comportamento comune e tuttavia sono anche specializzate. Questi sono un ottimo caso d'uso per una classe o un'interfaccia di base comune, con implementazioni e comportamenti specializzati, ovvero una gerarchia di classi (polimorfismo).

  • registrazione, ad esempio, perché semplifica la sostituzione di un altro logger

  • grandi parti della struttura del programma, perché evochi più di una simultanea, e forse approfitti dei processori multi cpu. Ad esempio, un server Web può utilizzare banalmente più gestori di richieste simultanee, a causa di oggetti.

Facilita il refactoring e il riutilizzo, come ho già detto, incoraggia una buona astrazione, che facilita la manutenzione. OOP dovrebbe essere abbracciato e usato tutto il tempo. Una buona programmazione OOP evita metodi statici e / o dati statici e usa oggetti per tutto.


6
Non ho votato a fondo (anche se ci sono stato vicino), ma penso che questo sia il motivo dei voti che hai ottenuto: "Usa sempre questo, perché è fantastico" raramente è un buon consiglio. Ci sono sempre delle eccezioni. Nessuno strumento è privo di inconvenienti e OOP non fa eccezione. Di 'alle persone che è buono, di' alle persone per cosa è buono, di 'alle persone perché è buono, di dire alle persone di evitare le alternative se possono, ma non dire mai alle persone di non pensare alle alternative.
cmaster,

@cmaster, sto bene se le persone decidono di votare, è una loro scelta, e l'ho fatto anch'io. Per quanto riguarda l'argomento, penso ancora che questa sia la risposta giusta per la persona che pone la domanda; IMHO, l'OP deve saltare fino in fondo e usare OOP, invece di provare a decidere quando usare OOP e occasionalmente scegliere di fare una classe ma altrimenti scrivere codice procedurale.
Erik Eidt,

2
@cmaster Posso apprezzare i consigli di Erik. Ogni volta che il tipo di risposta "dipende" può essere la strada politicamente corretta, ammettiamolo gente, OO è praticamente diventata la base per gli ambienti di programmazione che la supportano. Quindi non prendiamoci in giro, difficilmente puoi sbagliare con OO. Lo script descritto è, sebbene lineare, abbastanza complesso da consentire agli oggetti di apportare alcuni vantaggi.
Martin Maat,

2
@ErikEidt "l'OP deve saltare fino in fondo e utilizzare OOP" Potresti parafrasarlo come "L'OP deve smettere di pensare al modo migliore per risolvere il problema del cliente e seguire solo il vero percorso verso l'illuminazione". Purtroppo, ho avuto a che fare con un sacco di professionisti cosiddetti di calcolo che fanno seguire quella metodologia di progettazione del software. Cartone animato Dilbert obbligatorio: dilbert.com/strip/1996-02-27
alephzero

1
per quanto sia facile evitarlo come "un altro zelante OOP insensato", penso che ci sia qualcosa da dire per andare davvero al 100% in qualcosa per interiorizzarlo e assorbirlo. non così puoi usarlo ogni giorno per il resto della tua vita, ma così impari davvero i punti di forza e di debolezza e non solo leggi su di essi. Consiglierei a chiunque di passare qualche mese a fare OOP hardcore e qualche mese FP hardcore (come l'hakell) e qualche mese in C procedurale e così via. basta entrare e scendere e sporcarsi.
Sara,

-2

La programmazione orientata agli oggetti fornisce strumenti per creare un framework. Questi strumenti sono incapsulamento, astrazione, ereditarietà e polimorfismo. Queste idee ti aiuteranno a dividere il tuo programma in due sezioni.

Come: questa è la parte del frame del tuo codice, in cui crei una sorta di astrazione, decidi come funzionano i tuoi blocchi in generale e come interagiscono con altri blocchi.

Cosa fare - Questa parte è dove i blocchi eseguono il lavoro vero e proprio. Qui le classi sono derivate dalle classi di base create nella sezione "Come fare".

Si può trarre grandi vantaggi da OOPS

  1. se puoi riutilizzare un framework esistente e devi solo implementare dettagli specifici nella sezione "cosa fare".
  2. La funzionalità che viene implementata per il progetto corrente è di tipo generico / comunemente usato e altri progetti / progetti futuri possono trarre vantaggio dal framework creato durante lo sviluppo del progetto corrente.
  3. Suddividere progetti enormi in schemi comunemente conosciuti per risolvere un grosso problema.
  4. Usa OOPS anche per piccoli progetti per prendere l'abitudine di usarlo ed essere pronto quando si presentano 1-3 tipi di problemi

Quindi in pratica stai dicendo che dovresti sempre usare OOP, indipendentemente dal vero compito che vuoi risolvere?
JacquesB,

No :), ci sono molti padigrammi di programma là fuori e alcuni si prestano a risolvere un problema particolare meglio di altri. OOPS non è affatto la migliore soluzione per tutti, ma OOPS è piuttosto popolare. ci vorrà tempo e pratica per costruire una buona classe e strutture in OOPS, quindi se si desidera utilizzare OOPS in modo efficiente, iniziare meglio con progetti più piccoli. Una volta che lo padroni, dipende interamente da te. Vedo i concetti di OOPS come uno strumento per costruire principalmente framework.
Rahul Menon,
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.