Come scoprire effettivamente cosa si deve fare nella progettazione orientata agli oggetti?


12

Prima una dichiarazione di non responsabilità: non so davvero se questa domanda si adatta a questo sito Web, ma trovo ancora una domanda rilevante non solo per me ma per le altre persone che sono principianti. Se la domanda può essere migliorata per adattarsi qui, si prega di sottolineare i commenti int. Se non va bene, fammi sapere anche e, se possibile, fammi sapere dove questo può essere discusso perché non ho trovato buoni forum per questo.

Ho imparato a programmare nel 2009 quando ho studiato PHP. Più tardi, nel 2012, sono passato a C # e .NET. Comunque, la codifica non è il problema, la scrittura di algoritmi non è il mio problema. Il mio vero problema è sapere cosa deve essere codificato per raggiungere un requisito e dove deve essere codificato.

La maggior parte dei corsi disponibili sul web affronta il come : come scrivere codice in una determinata lingua, come utilizzare alcuni set di API, ecc. Non è questo il punto.

In questi anni ho letto molte cose: analisi e progettazione orientate agli oggetti, modelli di progettazione, progettazione guidata dal dominio e così via. Comprendo ad esempio i principi SOLID, alcune delle idee principali di DDD come la necessità di coinvolgimento di esperti di dominio, lo sviluppo di un linguaggio onnipresente e così via. Oserei dire che ho un background teorico almeno ragionevole.

Ma quando si tratta di pratica mi sento come un disastro. Qualche tempo fa dovevo continuare lo sviluppo di un sistema finanziario che era già stato sviluppato da qualcun altro. È quel tipo di "vecchio sistema" sviluppato con C # e WinForms. Era la prima volta che sceglievo un progetto con una complessità di dominio reale, con molte regole aziendali e così via.

Confesso che quando ricevo i requisiti per la maggior parte del tempo penso "come diavolo può essere fatto?" - Non ho idea di come iniziare a lavorare sui requisiti per capire cosa bisogna fare. Le mie principali confusioni credo siano ciò che devo codificare, quali classi, interfacce e dove ogni pezzo di logica va, su quale classe deve essere ogni cosa. Il problema è che non so da dove cominciare.

Il più delle volte, con un bel po 'di pensiero, finisco con alcune idee, ma non so mai come giudicare se la mia idea è corretta o no.

Voglio dire, non penso che questa sia una mancanza di teoria, come ho detto di aver letto su un sacco di cose sull'architettura del software e sull'orientamento agli oggetti, mi è stato consigliato, ma non è stato di grande aiuto nell'identificare cosa si deve fare in pratica .

Quindi, come posso imparare a fare davvero un design orientato agli oggetti? Quello che voglio imparare è: determinati requisiti sanno come iniziare a lavorarci su in un processo che porta a scoprire cosa deve essere fatto e dove ogni parte di codice appartiene. Come posso anche imparare a giudicare se la mia idea è corretta o no?

Credo che spiegarlo appieno come una risposta qui non sarebbe possibile. Quello che sto cercando, tuttavia, che può essere secondo lo stile del sito sono le risposte che danno solo una panoramica e indicano alcuni riferimenti (libri, corsi online, ecc.) Che possono essere utilizzati per espandere le idee e imparare davvero queste cose.


1. Comprendi già tutti i concetti fondamentali di C #, comprese cose come la differenza tra il sovraccarico dell'operatore e l'override dell'operatore, che cos'è una classe astratta e come è diversa da un'interfaccia, incapsulamento, polimorfismo, ecc.? Conoscere prima queste cose è essenziale per comprendere appieno OO in C #. Vedi c-sharpcorner.com/technologies/oop-ood .
Robert Harvey,

2
2. Le applicazioni più vecchie scritte in Winforms tendono a trasformarsi in grandi sfere di fango a meno che non siano progettate correttamente. La separazione delle preoccupazioni diventa fondamentale. Vedi winformsmvp.codeplex.com
Robert Harvey,

1
Non c'è davvero un processo. Il design consiste principalmente nel saper organizzare, che viene fornito con esperienza. I principi SOLID sono un buon inizio, ma non sono sufficienti e le persone tendono a perdersi in SOLID e dimenticano perché esistono i principi.
Robert Harvey,

1
Inizia poco. I requisiti sono problemi. Un problema può essere enorme come "Vogliamo sviluppare il prossimo sito Stackexchange" o solo "Vogliamo che il nostro prossimo Stackexchange abbia un accesso". Trasforma un grosso problema in molti ma più piccoli. Nel complesso, concediti la possibilità di fare prima le cose "sbagliate" e migliorare nel tempo.
Laiv

1
Voglio contemporaneamente votare e vtc questo ...
svidgen,

Risposte:


21

Quindi, come posso imparare a progettare veramente oggetti orientati? Quello che voglio imparare è: determinati requisiti sanno come iniziare a lavorarci su in un processo che porta a scoprire cosa deve essere fatto e dove ogni parte di codice appartiene. Come posso anche imparare a giudicare se la mia idea è corretta o no?

Bene, prima di tutto, smetti di pensare al design orientato agli oggetti come corretto. È come pensare all'inglese come corretto.

Il paradigma orientato agli oggetti non è corretto. Ha alcuni vantaggi e svantaggi. È un ideale. Non è il nostro unico. È meglio di niente ma non è certamente tutto.

Ho programmato per decenni ormai. Ho studiato queste cose per quasi finché sono esistite le idee. Sto ancora imparando cosa significa. Gli esperti stanno ancora imparando cosa significa. Il nostro intero campo ha meno di 100 anni.

Quindi, quando prendi una pila di requisiti e scopri un codice che li soddisfa, ma senti che il codice che hai scritto è un disastro tragico, non sei solo. Il codice di lavoro è semplicemente il primo passo verso un ottimo codice. Codice che non solo funziona ma che altri possono leggere e capire facilmente. Codice che può essere adattato rapidamente quando cambiano i requisiti. Codice che ti fa venire voglia di rilassarti e dire "Wow, è così semplice".

Il problema è che non siamo pagati per fare tutto ciò. Facciamo tutto questo perché siamo professionisti. Dobbiamo fare tutto ciò quando il capo non guarda perché c'è sempre una scadenza. Ma vogliamo tornare tra 5 anni e dire ai neofiti: "Oh sì, l'ho scritto. Funziona ancora eh? Fantastico."

Come ci si arriva? Pratica. Non accettare QUALSIASI idea di design sulla fede. Qualcuno non starà zitto su come il design guidato da eventi semplifica questo design? Non sei sicuro che abbiano ragione? Costruisci il tuo progetto giocattolo a casa che utilizza il modello di osservatore. Pasticcia con esso. Prova a trovare cose che NON aiutano.

Leggere. Domanda. Test. Ripetere.

Quando arriverai al punto in cui l'hai fatto per l'80% della tua vita, sarai confuso quanto me.

Confesso che quando ricevo i requisiti per la maggior parte del tempo penso "come diavolo può essere fatto?" - Non ho idea di come iniziare a lavorare sui requisiti per capire cosa bisogna fare. Le mie principali confusioni credo siano ciò che devo codificare, quali classi, interfacce e dove ogni pezzo di logica va, su quale classe deve essere ogni cosa. Il problema è che non so da dove cominciare.

Mi sentivo allo stesso modo. Poi ho scoperto la gioia del refactoring. Sii disposto ad adattare i disegni mentre scrivi il codice. Cercare di elaborare tutto su carta in anticipo è il modo più difficile per farlo. Scrivi codice che può essere smentito, dimostralo errato e correggilo.


2
Questa è un'ottima risposta Sto programmando da 15 anni e aggiungerò che l'intero campo dell'ingegneria del software (la mia professione) è "sfocato" - è un mix di arte e funzione e, a seconda dello sviluppatore, è più uno dell'altro. Posso venire in mente un'idea per un'architettura su carta, ma non riesco mai a elaborare i dettagli del design di OO fino a quando non mi immergo nella confusione, trovo in giro e trovo cosa funziona e cosa no.
Jropella,

Grazie per la risposta! Quindi il tuo punto è: una volta che abbiamo almeno una soluzione per implementare un requisito, e funziona, lo implementiamo, e quindi quando vediamo come si collega all'altro codice e altri requisiti, lo refattiamo per renderlo migliore? Ma ci sono ancora situazioni in cui ottengo alcuni requisiti e non ho idea di come iniziare. In questi casi, hai qualche consiglio su come iniziare? A volte credo che il meglio sarebbe discutere i requisiti e le possibili implementazioni, ma lavoro da solo. C'è qualche forum in cui questo tipo di discussione è il benvenuto?
user1620696

2
Bene, prima di tutto smetti di lavorare da solo. Anche avere un principiante all'oscuro che ti rallenta per spiegare le cose è meglio di così. In secondo luogo, impara a suddividere un requisito in parti. Continuate a farlo fino a quando non avrete qualcosa di gestibile su cui potete ottenere trazione. Scrivi una prova del codice concettuale in un ambiente completamente diverso, se necessario. Fai semplicemente qualcosa che esprima la tua comprensione di ciò che è necessario. Quindi prova quell'espressione. La mia scoperta è che hai fatto delle ipotesi sbagliate. Quello è buono. Sii disposto a cambiarli.
candied_orange

1

Lo sviluppo del software si riduce alla consegna di software funzionante, in tempo, a budget rispettando tutti i criteri di accettazione. Supponendo che tu sia riuscito a farlo, la qualità percepita del codice o della sua struttura è una preoccupazione secondaria.

Il problema ovviamente è che scrivere un nuovo codice greenfield nuovo tende ad essere molto più economico e più semplice rispetto al mantenimento del codice legacy, quindi piuttosto che essere troppo impegnato nella qualità del codice o nell'architettura, ricorda che il tuo vero problema è la manutenibilità.

In genere il codice è considerato mantenibile quando i costi, i tempi e i rischi associati alla modifica di quel codice sono sufficientemente bassi in modo tale da correggere i bug o implementare le modifiche ai requisiti e che implementando tali modifiche non si perpetua una "spirale della morte" "di codice-entropia.

Al contrario, il codice è considerato non mantenibile quando non è possibile modificare o eseguire il refactoring in modo sicuro senza un serio rischio di rompere qualcosa o di spendere troppo tempo / denaro per garantire che non si rompa nulla, vale a dire quando il tempo, i costi e il rischio associati all'utilizzo di quel codice sono sproporzionatamente elevato rispetto ai vantaggi di apportare modifiche (ad esempio il datore di lavoro o il cliente non sta perdendo denaro aggiungendo nuove funzionalità, correggendo bug, ecc.)

Ricorda che anche il pasticcio di spaghetti più diabolico può essere potenzialmente mantenibile se hai abbastanza disposizioni intorno al pasticcio per proteggerti dalle rotture (anche se questi casi sono rari). Il problema con un pasticcio di spaghetti è che proteggerlo dalle rotture cambia in modo piuttosto costoso e inefficiente, specialmente se lo stai facendo in modo retrospettivo.

Forse il modo più affidabile per assicurarti di aver scritto codice gestibile è quello di scrivere (dove ragionevolmente possibile) una serie adeguata di test automatizzati allo stesso tempo (sfruttando al massimo tutti gli altri strumenti di analisi statica che potrebbero essere disponibili).

In particolare, non è necessario seguire una rigorosa metodologia di sviluppo come TDD / BDD per finire con test automatici sufficienti per consentire il refactoring; basta abbastanza per proteggere il codice contro le modifiche rottura accidentale in futuro.

Se il tuo codice è coperto da test automatici, puoi rilassarti sul suo design e sulla sua struttura sapendo che sei coperto da quei test; puoi rifattorizzare in modo aggressivo in un secondo momento o addirittura buttarlo via e ricominciare.

Questo pone la domanda su come scrivere codice facilmente testabile; questo è in genere l'argomento principale per i seguenti principi SOLIDI; infatti, il segno distintivo del codice che aderisce ai principi SOLID è che è facile e conveniente / economico scrivere unità di test.

Certo, a volte non hai nemmeno il tempo per scrivere unit test; tuttavia se hai scritto tutto il tuo codice tenendo presente la domanda "Come posso scrivere test automatici per questo?" (anche se non hai effettivamente implementato quei test), probabilmente sei anche riuscito a trovare un design ragionevolmente gestibile.


1
non abbiamo mai tempo per scrivere test automatici, ma abbiamo sempre tempo per eseguire test manuali più e più volte ...
Nick Keighley,

Allo stesso modo, non abbiamo mai tempo di scrivere il codice "correttamente" e "in modo pulito" la prima volta, ma sembra che ci sia tempo infinito per continuare a tornare indietro e sistemarlo, ancora e ancora e ancora a causa della mentalità sbagliata ma così diffusa presentata in questo post.
Dunk,

@Dunk Non credo sia realistico aspettarsi che il codice non debba mai cambiare o essere rivisitato. Le pratiche di unit test e le linee guida SOLID riguardano pratiche incoraggianti che comportano la modifica di codice facile ed economico quando si verifica l'inevitabile, ad esempio qualcuno trova un bug oscuro davvero strano che lo sviluppatore non ha preso in considerazione in quel momento o il cliente vede il soluzione e modifica dei requisiti, o anche il codice originale conteneva errori perché gli sviluppatori sono solo umani; o forse lo sviluppatore ha frainteso i requisiti o ha scoperto limiti tecnici precedentemente sconosciuti ...
Ben Cottrell,

1
@BenCottrell - Sono completamente d'accordo. Il codice dovrà sempre essere rivisitato. Tuttavia, a causa di ciò, induce le persone a puntare a dedicare del tempo alla "progettazione iniziale" e alla scrittura di un "codice pulito" come una sorta di errore. Usano il mantra "puntuale" e "on-budget" per giustificare un codice / progetto scadente. Puoi usare tutte le "pratiche" che vuoi ma non ti comprerà "codice che è facile ed economico da cambiare" senza avere un buon design e un "codice pulito" per cominciare. Una buona progettazione e un "codice pulito" avranno il sottoprodotto di raggiungere effettivamente l'obiettivo nei tempi previsti e nel budget.
Dunk,

@Dunk Sembra che tu stia dicendo che molti sviluppatori non si preoccupano della qualità del codice, cosa che di solito non credo. In realtà penso che ci siano due problemi più grandi: in primo luogo, mentre gli sviluppatori possono essere quelli che forniscono una stima per il budget e la scadenza, le stime possono facilmente risultare errate. In secondo luogo, le parti interessate del progetto hanno l'ultima parola su tempi / costi, il che significa che rischi, budget e scadenze prevalgono sui problemi tecnici. Data la scelta tra "decisamente in ritardo / budget eccessivo" o "codice potenzialmente negativo", trovo che le parti interessate scelgano spesso quest'ultimo.
Ben Cottrell,
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.