Come affronti il ​​design di classe negli OOP?


12

Quando provo a progettare una soluzione OO, generalmente utilizzo il modello CRC in cui elenco i nomi delle classi (nomi), cosa fanno (verbi) e come collaborano con altre classi.

Questo blog ha la seguente cosa da dire su questo approccio sostantivo-verbo

   ...This approach, which I will call “noun and verb,” is so limited 
   I’ll dare to call it brain damaged....

La mia domanda è: esiste una migliore tecnica di modellazione per utilizzare l'approccio OO?


1
Supponendo che l'offerta $$$ abbia senso, basta iniziare a scrivere codice. Quando bloccato, trova un modo per rimuovere gli ostacoli. Ripensare più tardi. "CRC" non è qualcosa di cui ho sentito parlare prima d'ora, ma ciò non mi ha impedito di scrivere lezioni. Se ci fosse un grande principio meccanico là fuori, qualcuno avrebbe creato un buon strumento di analisi del codice che lo utilizzava e sarebbe popolare. Fino a quando non avrò trovato una cosa del genere, continuerò a usare il mio intuito. Certo, bisogna usare verbi e nomi nei posti giusti ...
Giobbe

1
Yeesh. Basta avere un rapido modello mentale del sistema e iniziare a scrivere codice. So che molti non saranno d'accordo con me qui, ma puoi analizzare troppo queste cose a morte. Fintanto che hai una discreta quantità di esperienza devi dare un'idea di cosa funzionerà e non funzionerà. Se qualcosa si rivela difficile con cui lavorare in anticipo, cambiarlo e ora hai ancora più esperienza.
Ed S.

Risposte:


12

In tutta onestà, ha aggiunto "In fun" a tale affermazione.

Fino ad oggi, tendo a modellare i sistemi usando l'approccio "sostantivo e verbo", ma negli anni ho scoperto che TDD ci insegna che questo approccio focalizza l'attenzione su ciò che è sbagliato. In questo senso, il blogger ha ragione. Tuttavia, non sono sicuro che sia l'approccio in difetto, piuttosto che il modo in cui funzionano le nostre menti.

Se vuoi provare una piccola sfida qui, smetti di leggere e prova a modellare il gioco Monopoly, usando la lingua inglese, quindi torna qui.

Sospetto che la tentazione sarà quella di guardare immediatamente gli oggetti con cui interagiamo molto - il tabellone, gli spazi, le carte, i dadi, i pezzi - ma non è qui che va la maggior parte della logica. La maggior parte di questi oggetti sono completamente stupidi. Dati, se vuoi.

Ma non appena inizi a scrivere test, ti rendi conto di quale oggetto è di gran lunga il più importante in qualsiasi gioco: le regole.

Ricordi quel pezzettino di carta che hai letto una volta quando hai iniziato a giocare e non interagire di nuovo fino a quando non c'è una disputa? La versione computerizzata non funziona in questo modo. Ogni singola cosa che il giocatore cerca di fare, un computer consulterà le regole e vedrà se gli è permesso farlo o no.

Quando ci pensi, fai la stessa cosa, ma poiché ci vuole tempo per leggere le regole cartacee e il tuo cervello ha un ragionevole sistema di memorizzazione nella cache, consulta le regole nella tua testa. Un computer probabilmente troverà facile leggere nuovamente le regole, a meno che non siano archiviate nel database, nel qual caso potrebbe anche memorizzarle nella cache.

E questo è il motivo per cui TDD è così popolare per il vero design di guida. Perché tende a guidare rapidamente il processo di pensiero nei posti giusti:

Quando penso che scriverò alcuni test per il mio gioco Monopoli. Potrei guardare il mio set e provare a trovare gli oggetti. Quindi, abbiamo questi pezzi. Scriverò alcuni test per quelli.

Forse avrò un MonopolyPiece di classe base e ogni tipo di pezzo deriverà da quelli. Inizierò con DogPiece. Primo test ... ahh. In realtà, non c'è logica qui. Sì, ogni pezzo verrà disegnato in modo diverso, quindi potrei aver bisogno di un DogDrawer, ma mentre sto completando il gioco, voglio solo scrivere "D" sullo schermo. Aggiungerò l'interfaccia utente alla fine.

Troviamo qualche logica reale da testare. Ci sono molte di queste case e hotel, ma non hanno bisogno di test. Denaro, no. Carte di proprietà, n. E così via. Anche la scheda non è altro che una macchina a stati, non contiene alcuna logica.

Scoprirai rapidamente che hai ancora tre cose in mano. Le carte Chance e Community Chest, una coppia di dadi e un set di regole. Queste saranno le parti importanti da progettare e testare.

L'hai visto arrivare quando hai scritto i nomi e i verbi?

Vi è, infatti, un grande esempio in Agile Principles Patterns and Practices di Robert Martin in cui cercano di dare forma ad un'app Bowling Score Card usando TDD e trovano ogni genere di cose che pensavano fossero delle classi ovvie, per le quali non valeva la pena preoccuparsene.


Non riesco a capire perché TDD sia una risposta all'analisi OO richiesta dall'OP. Noun / verb è la primissima approssimazione del dominio problematico (più utile per i principianti) e, naturalmente, le classi di perfezionamento possono essere fatte in un secondo momento, ma l'affermazione TDD dirige il design nella giusta direzione è IMHO chiaramente sbagliato (suggerisci davvero di saltare la pianificazione , progettare e iniziare a programmare ?!). Anche l'esempio di Monopoli è fuorviante, a seconda della parte del sistema su cui stai lavorando: UI o logica di base. Sul lato dell'interfaccia utente taglia e quant'altro ha perfettamente senso.
Roman Susi,

+1 e preferito. In primo luogo, la mia esperienza è che TDD guida rapidamente il processo di pensiero nei posti giusti (a volte potresti discutere "rapidamente"). E può aiutare a rivelare presto i difetti di progettazione: imparerai l'iniezione di dipendenza se non altro! Noun-Verb - chi non inizia qui? Ma la maggior parte di questi oggetti è completamente stupida. I dati, se vuoi, sono profondi. Il titolo di un libro fondamentale dice tutto per me Algorithms + Data Structures = Programmi
radarbob

3

Non ho mai trovato tali metodi utili per me. In effetti ho scoperto che usarli mi confonde di peggio. Dai un'occhiata alla Caffettiera di Robert C. Martin , non credo che usi questo tipo di approccio.

Una cosa che mi infastidisce subito è la soluzione a cui la persona arriva nell'articolo CRC a cui ti colleghi. La collaborazione cliente / ordine non è qualcosa che riterrei utile, non come scritto comunque. Non c'è nulla di particolarmente interessante in quel modello su un cliente che merita lo status di classe. L'unica cosa interessante di essere un "cliente" è che ci sono uno o più ordini associati a quella persona .

Anche il modello del college. C'è molto che può, e probabilmente dovrebbe essere condiviso tra Studente e Professore. Inoltre, cosa succede quando un professore partecipa a una lezione, come spesso è consentito gratuitamente nei campus universitari?

Suppongo che potrebbe essere una pratica utile, un elemento nel toolkit di progettazione. Non credo che dovrebbe essere l'unico modo in cui approcci il design almeno. Francamente, trovo più utile l'approccio dell'analisi di comunanza / variazione. Mi sembra di modellare molto attentamente ciò che facciamo nel classificare le astrazioni durante la vita di tutti i giorni.

Modifica: ho appena letto metà del secondo blog e devo dire che sono abbastanza d'accordo. Dovrò leggere il resto e vedere cosa offre in termini di apprendimento.


2
Errore: riga 2: collegamento ipertestuale non valido!
Cracker,

1
Il software SE l'ha nascosto. Funzionava benissimo in anteprima. Ecco il link in formato testo: objectmentor.com/resources/articles/CoffeeMaker.pdf
Edward Strange

0

La mia opinione è che le classi dovrebbero essere aggiunte (e rimosse) durante la codifica per separare le preoccupazioni e ridurre le dipendenze. Essere fluenti nei modelli di progettazione è probabilmente una buona scommessa per vedere le possibilità di refactoring e semplificazione.

Le classi in generale, nella mia esperienza, non rientrano ordinatamente nelle categorie nome / verbo ma piuttosto finirai con un mix di classi nome / verbo insieme a diverse classi modello (fabbriche, singleton, modelli strategia ecc.) E altre classi manageriali che affronta un aspetto della tua applicazione.

La cosa fondamentale è che il tuo obiettivo dovrebbe essere quello di poter guardare una classe e dedurre ciò che fa e modificarlo cambiando solo quella classe. Più codice per un aspetto dell'applicazione viene distribuito tra le classi, più diventa difficile seguirlo, gestirlo ed estenderlo.

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.