Perché è utile suddividere un programma in più classi? [chiuso]


62

Sono ancora uno studente al liceo (che frequenta la terza media) e devo ancora frequentare un vero corso di informatica a scuola. Tutto ciò che ho fatto finora è attraverso i libri. Quei libri mi hanno insegnato concetti come l'ereditarietà, ma in che modo può essere utile suddividere un programma in più classi? I libri non me l'hanno mai detto.

Lo sto chiedendo principalmente a causa di un recente progetto. È un videogioco arcade, un po 'come un gioco Flash, come hanno detto alcune persone (anche se non ho idea di cosa sia un gioco Flash ). Il fatto è che è solo una classe. Funziona perfettamente (un po 'di ritardo occasionale) con una sola classe. Quindi, sto solo chiedendo come dividerlo in più classi lo aiuterebbe.

Questo progetto era in Java e io sono l'unica persona che ci lavora, per la cronaca.


1
Per rendere più semplice ogni parte del software! infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
TehShrike

49
Quando leggi i tuoi libri, erano divisi in capitoli e sezioni? Abbiamo diviso un programma in classi per organizzare le cose, proprio come i libri dividono il testo in capitoli per organizzare le cose.
riwalk

12
I romani dicevano: divide et impera.
Giorgio,

7
@Giorgio: o in inglese, perché il latino non è più così usato: Divide And Conquer .
Matthieu M.,

40
Considerando che sei al grado 10 e hai già potuto formulare una domanda intelligente, fornendo tutti i dettagli necessari per ottenere risposte valide, fornendo il contesto e la tua esperienza relativa, nonché informazioni di base sul perché stai ponendo la domanda; sei già più qualificato di molte persone con cui lavoro attualmente ...
CaffGeek,

Risposte:


71

La risposta più semplice è che se metti tutto in una classe, devi preoccuparti di tutto in una volta quando scrivi un nuovo codice. Questo può funzionare per piccoli progetti, ma per enormi applicazioni (stiamo parlando di centinaia di migliaia di righe), questo diventa rapidamente quasi impossibile.

Per risolvere questo problema, scomponi le funzionalità nelle loro classi e incapsuli tutta la logica. Quindi, quando vuoi lavorare sulla classe, non devi pensare a cos'altro succede nel codice. Puoi semplicemente concentrarti su quel piccolo pezzo di codice. Questo è prezioso per lavorare in modo efficiente, tuttavia è difficile apprezzarlo senza lavorare su applicazioni enormi.

Naturalmente ci sono innumerevoli altri vantaggi nel suddividere il codice in parti più piccole: il codice è più gestibile, più testabile, più riutilizzabile, ecc., Ma per me il vantaggio maggiore è che rende gestibili programmi di massa riducendo la quantità di codice bisogno di pensare contemporaneamente.


7
Molti concetti / idee nella programmazione (principi OO, controllo del codice sorgente distribuito, standard di codifica) hanno davvero senso solo quando si lavora su progetti relativamente grandi in un team. Capirai perché quando lavori effettivamente su tali progetti.
joshin4colours,

40
Vale la pena notare che semplicemente suddividere il progetto in più classi / file non aiuta molto. La cosa veramente importante è avere classi autonome , quindi cambiare una classe non richiede sapere altro sul programma (e usare la classe non richiede alcuna conoscenza di come è stata implementata). Ne ho parlato perché vedo spesso codice con molte classi, ma nessun vero incapsulamento. L'incapsulamento è la parte importante: come raggiungerla sono solo dettagli.
Ripristina Monica il

2
Alcune parole chiave sarebbero "accoppiamento" o "disaccoppiamento", "incapsulamento", "occultamento delle informazioni".
marktani,

@BrendanLong, sono d'accordo e aggiungerò anche che l'incapsulamento è quasi impossibile. A meno che tu non stia scrivendo programmi separati ovviamente ... MA di solito ci sono molte parti che non dipendono l'una dall'altra, ma hanno solo dipendenze condivise
Jo So

29

Bene, la risposta più semplice potrebbe essere "Aiuta a organizzare le cose". Se non altro, potresti confrontarlo con le sezioni di un notebook: è semplicemente più semplice se hai "tutto ciò che riguarda l'interfaccia utente" qui e "tutto ciò che riguarda il gameplay" laggiù.

La risposta più sofisticata è che dividere il lavoro non è solo conveniente, ma molto importante per gestire la complessità (e "gestire la complessità" è praticamente il nome del gioco quando si tratta di programmazione). Le classi o altri tipi di moduli ti consentono di "separare le preoccupazioni". Non solo sai dove cercare "elementi correlati all'interfaccia utente", ma puoi essere sicuro che se vuoi apportare una modifica all'interfaccia utente, puoi semplicemente farlo in un unico posto e non devi preoccuparsi "ora, è l' unico posto in cui ho impostato il mio carattere su Comic Sans?". E puoi apportare una modifica e sapere che l'effetto di tale modifica è solo per qualsiasi ambito (piccolo) sia appropriato. Se tutto è in una singola classe o modulo, essenzialmente tutto è globale,

Nel caso specifico delle classi come tipo di modulo software, c'è anche un sacco di comportamento associato a una classe, e la maggior parte degli sviluppatori nel paradigma orientato agli oggetti trova molto utile avere nomi significativi associati alle classi che sono correlate al gruppo funziona insieme. Quindi probabilmente non avresti effettivamente una UIlezione, probabilmente avresti una Buttonlezione. C'è un intero corpus di conoscenze e tecniche associate alla progettazione di classi orientate agli oggetti ed è il modo più comune di organizzare grandi sistemi nella programmazione tradizionale.


12

Questa è una buona domanda! Semplice e ben chiesto. Bene ... la risposta non è così facile da capire per uno studente che sta studiando informatica e probabilmente non lo sa in profondità OO e probabilmente non ha esperienza lavorativa.

Quindi, posso rispondere descrivendo uno scenario e facendoti immaginare come il software multi-classe sia migliore del software monolitico (creato da una sola classe):

  • Leggibilità : è molto più difficile navigare e scrivere codice all'interno di un file con 10000 righe rispetto a diversi file piccoli e organizzati.
  • Riutilizzabilità : se scrivi una singola classe, puoi scivolare nella duplicazione del codice . Ciò significa più righe di codice e probabilmente più bug (!)
  • Testabilità : per quanto riguarda il test di una singola funzionalità? Se isola una funzionalità logica in una classe, la tua vita sarà più semplice.
  • Manutenibilità del codice : puoi correggere un bug o migliorare la funzionalità con le classi multiplie in un unico posto: le piccole classi carine.
  • Struttura del progetto : oooooh puoi immaginare quanto brutto apparirà un progetto con un solo file sorgente?

Mi piace la tua risposta e ho appena apportato alcune modifiche (che devono ancora essere sottoposte a revisione paritaria). Un punto che mi manca è il rilevamento più semplice delle modifiche nei sistemi di versioning del software come SVN / GIT. È anche più facile lavorare in parallelo con più programmatori per un progetto.
Martin Thoma,

Direi che la separazione delle preoccupazioni, la coesione e il disaccoppiamento è un concetto che ha una portata molto più ampia rispetto alla disciplina di OOP. I programmatori imperativi, logici e funzionali si sforzano tutti per l'alta coesione e il basso accoppiamento.
Sara

8

Ci sono molte buone risposte qui, e sono decisamente d'accordo con loro, ma sento che c'è qualcosa di più degno di nota.

Al momento, come hai detto, stai lavorando da solo al tuo progetto. Tuttavia, in futuro, ci saranno momenti in cui dovrai lavorare in un ambiente di squadra. Durante quei periodi, dovrai dividere il lavoro (presumibilmente il progetto sarà abbastanza grande). Di conseguenza ci sono alcuni (immagino davvero due principali ) diverse opzioni. Puoi avere più copie di un file e lavorare su "pezzi" separati del file e poi "combinarli" con copia e incolla in seguito e quindi modificare in modo che le parti possano lavorare insieme, oppure puoi dividere quei "pezzi" abbastanza facilmente in classi diverse e discutere su come scrivere quelle classi, e utilizzare quella conoscenza per iniziare.

Sarà ancora necessario lavorare per integrare tutti i pezzi separati insieme, ma sarà molto più facile da mantenere. Perché il file x contiene il codice y e questo è il codice che sai che devi modificare. Questo va nell'organizzazione di cui parla la maggior parte delle altre risposte.

Tenendo un programma in testa. Link da Giorgio


1
+1: anche il lavoro di squadra è importante! Vedi ad esempio paulgraham.com/head.html e il paragrafo con il titolo "Non fare in modo che più persone modificino lo stesso codice".
Giorgio,

@Giorgio L'ho quasi sfiorato, ma sembra una risorsa fantastica! Lo aggiungerò alla mia risposta semplicemente perché alcune persone potrebbero non guardare nella sezione commenti. Sicuramente darò una lettura più approfondita qualche volta.
Sephallia,

Ciò vale anche per il controllo delle revisioni: lavorare su file separati significa meno conflitti e fusioni.
Ripristina Monica il

7

In effetti, ciò che hai fatto è stata reinventare la programmazione procedurale. Intendiamoci, è possibile scrivere software in quel modo e probabilmente il compilatore non se ne occuperà. Per molti anni le cose sono andate così fino a quando i computer non sono diventati più veloci e gli strumenti sono migliorati.

Detto questo, se suddividi il tuo codice in diverse unità logiche (Classi, moduli, ecc.), Puoi avere molte brevi parti di codice facili da capire. che può essere mantenuto in seguito. Molti dei miei moduli hanno meno di 20 righe di codice. So che tutto il codice su un determinato argomento si trova in un posto specifico. Significa anche che se qualcun altro si unisce al progetto, sarà molto più facile trovare le cose.

Come ha detto Gerald Sussman, i nostri programmi dovrebbero essere scritti prima in modo che le persone possano leggerlo e in secondo luogo in modo che il computer possa eseguirlo. (E se non hai ancora letto "Struttura e interpretazione dei programmi per computer", dovresti)


4

Uno usa più classi perché quando arrivi a cose più grandi scoprirai che non c'è modo di tenere traccia di tutto quando si tratta di una grande pila di codice.

Devi semplicemente dividere e conquistare per gestirlo.


3

La programmazione orientata agli oggetti è la migliore idea che abbia mai visto in programmazione. Ma non è la cosa migliore in tutti i casi, hai bisogno di un po 'di esperienza di programmazione per capirne il punto e molte persone affermano di fare OOP quando non lo sono.

Se riesci a cercare la "programmazione strutturata", probabilmente troverai qualcosa di più immediatamente utile. (Assicurati di leggere la vecchia programmazione strutturata. I vecchi termini spesso assumono nuovi significati più fantasiosi e non hai ancora bisogno di nulla di speciale.) Questo è un concetto piuttosto semplice di scomporre il tuo programma in subroutine, che è molto più facile di scomporlo in oggetti. L'idea è che il tuo programma principale sia una breve routine che chiama subroutine ("metodi" in Java) per fare il lavoro. Ogni subroutine sa solo cosa viene detto dai suoi parametri. (Uno di questi parametri potrebbe essere un nome di file, quindi puoi imbrogliare un po '. Quindi, guardando l'intestazione di un sottoprogramma / metodo ti dà una rapida idea di ciò che fa, fa quasi a colpo d'occhio.

Quindi tutte le subroutine sono suddivise in modo simile fino a quando alcune righe di codice senza alcuna chiamata di metodo faranno il lavoro. Un programma principale che chiama alcuni metodi, ognuno dei quali chiama alcuni metodi, ognuno dei quali .... Fino a piccoli metodi semplici che fanno il lavoro. In questo modo, puoi guardare qualsiasi parte di un programma molto grande (o piccolo programma) e capire rapidamente cosa fa.

Java è progettato specificamente per le persone che scrivono codice orientato agli oggetti. Ma anche il programma OO più intenso utilizza una programmazione strutturata e puoi sempre sovvertire qualsiasi lingua. (Ho fatto OO in semplice C.) Quindi puoi fare SP, o qualsiasi altra cosa, in Java. Dimentica le lezioni e concentrati su metodi grandi che possono essere suddivisi in metodi piccoli e gestibili. Dovrei aggiungere che SP aiuta molto a permetterti di riutilizzare il tuo codice, e anche con il principio DRY (google it, ma significa "Non ripetere te stesso").

Spero di aver spiegato perché e come suddividere il codice in più parti senza introdurre "classi". Sono un'ottima idea e sono la cosa giusta per i giochi e Java è un ottimo linguaggio per OOP. Ma è meglio sapere perché stai facendo quello che stai facendo. Lascia in pace OOP finché non inizia a dare un senso a te.


0

Uno dei vantaggi è la riutilizzabilità. Un programma è fondamentalmente un insieme di istruzioni raggruppate insieme. Scoprirai che alcune di quelle istruzioni sono adatte anche per altri programmi.

Diciamo che fai un gioco di salto. Più tardi, quando decidi di fare una partita a cannone, scopri che il calcolo della fisica che hai usato nel gioco del salto è utile qui.

Quindi, invece di scriverlo di nuovo, o peggio di copiarlo e incollarlo nel nuovo programma, lo trasformi in una classe. Quindi la prossima volta che realizzi un altro gioco in cui la meccanica del gioco richiede fisica, potresti semplicemente riutilizzarla. Naturalmente questo è semplificato ma spero che abbia senso.


0

Prima di tutto, nota che sono un C ++ e Python, non Java, quindi alcuni di questi potrebbero non essere applicati in modo così completo. Per favore, correggimi se faccio delle ipotesi errate su come funzionano le classi in Java.

Le classi sono utili soprattutto quando vengono istanziate. Una classe di cui non viene creata nessuna istanza è in realtà solo uno spazio dei nomi glorificato. Se usi tutte le tue classi in questo modo, in effetti, i vantaggi di spostare le cose dallo spazio dei nomi allo spazio dei nomi possono sembrare insignificanti: al massimo, vincerai avendo alcuni dati privati ​​in ciascuno e incapsulando un po 'le cose.

Tuttavia, non è qui che brillano le classi. Considera la Stringclasse: potresti avere tutte le stesse funzionalità usando chararray e alcune funzioni statiche. A questo punto, le funzioni ti danno un po 'più di sicurezza e zucchero sintattico. Puoi scrivere string.length()invece di length(char_array); non è un grosso problema, ma a molte persone piace ancora. Inoltre, sai che se qualcuno ti ha dato un String, è stato creato con il Stringcostruttore e deve funzionare con la lengthfunzione: se la versione dell'array non è in grado di gestire alcuni caratteri, non ha modo di impedirti di inserirli lì .

Comunque non è ancora così. Il punto chiave è che le classi raggruppano i dati e le funzioni che operano su di essi e ne astraggono entrambi. Quando hai un metodo void f(Builder b)che sai che otterrai Builder, e puoi aspettarti che supporterà determinati comportamenti. Tuttavia, non si sa nulla dei dati o delle funzioni in esecuzione - in effetti, le definizioni per entrambi potrebbero non essere ancora scritte mentre si scrive e si compila f.

Il primo punto da capire è quindi che le classi rendono conveniente il passaggio dei dati assicurandosi che non vengano interrotti. Il secondo punto è che sia i dati che la funzione (implementazioni) di un oggetto hanno qualcosa sull'oggetto, non qualcosa che si può semplicemente dire dal suo tipo.


0

L'intera idea si basa su una regola generale denominata divide and conquer .
Questo paradigma può essere usato quasi ovunque; dividi un problema in piccoli problemi e poi risolvi questi piccoli, semplici e noti problemi.
Dividere il tuo programma in classi è uno dei tipi di divisione che ha iniziato a diventare comune nell'ultimo decennio. In questo paradigma di programmazione modelliamo il nostro problema con alcuni oggetti e proviamo a risolverlo inviando messaggi tra questi oggetti.
Alcune persone potrebbero dire che questo approccio è più facile da comprendere, espandere e eseguire il debug.
Anche se alcune persone non sono d' accordo :)


0

Non si tratta di suddividere un programma in classi, ma di come modellare l'applicazione, ovvero come visualizzare parti dell'applicazione. Dividere le cose è solo un meccanismo che usiamo per comprendere meglio le cose complesse. Non è solo con la programmazione. Immagina un circuito stampato con molti fili intrecciati tra loro, formando una struttura complessa con ogni filo collegato da qualche parte (codice spaghetti). Dovrai seguire ogni filo fino alla fine per capire le connessioni. Al contrario, immagina fili raggruppati e codificati a colori secondo la loro funzione. Diventa molto più facile riparare le cose.

L'idea è che non inizi con un programma lungo e poi lo dividi in classi. Ma modellare prima l'applicazione in termini di oggetti / classi e quindi collegarli per creare applicazioni.

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.