Come applicare uno dei concetti OOP (Chiuso per modifica e Aperto per estensione)?

4

Giorni prima, ho creato domande, quiz e classi principali. Un quiz ha una o più domande. Dalla classe principale, prima creo oggetti Question (il costruttore accetta una serie di numeri). Il Quiz è come quando visualizzo le domande omettendo l'ultimo numero dell'array e l'utente proverà a capire quel numero. Poi da Main ho creato un oggetto Quiz. Da Main I chiamo solo i metodi della classe Quiz e da Quiz Class I chiamiamo solo metodi nella classe Question.

Poi ho anche creato un'applicazione web (con JSP e Servlets) che utilizza le stesse classi di domande e quiz ma non Main. Invece di Main ho usato JSP e Servlets per visualizzare i dati. Quindi, senza modificare le classi del modello (Quiz e Domanda) sono in grado di usarle da altre applicazioni.

Ma ora ho bisogno di aggiungere un SUGGERIMENTO, che fornirà suggerimenti all'utente per ogni domanda. Se vado a modificare queste 2 classi modello, violerò il principio Open-Close. Se sto andando a creare una classe chiamata Hint (un suggerimento per ogni domanda) ed estendo dalla classe delle domande, non ha senso perché il suggerimento non è una domanda. Ma la domanda ha un suggerimento.

Puoi guidare come avere un SUGGERIMENTO nella mia applicazione in modo che io usi le classi precedenti senza modifiche e violando i concetti OOP?

    
posta user18651 15.05.2011 - 06:39
fonte

3 risposte

5

Non vedo perché vorresti essere così pignolo riguardo ai principi OOP. OOP è fantastico, ei principi sono validi, ma poi di nuovo ogni progetto ha le sue particolarità. Voler essere OOP-perfetto a tutti i costi mi sembra un inconveniente.

Più codice, più flessibile sono con questi principi. Non sono qui per rendere la vita più difficile, sono qui per rendere più pulito il tuo codice. Se il tuo codice è pulito e ha un senso, al diavolo i principi.

Aggiunta di un metodo di "suggerimento" alla tua classe di domande, che non restituisce nulla se non c'è alcun suggerimento o che non viene chiamato dalle tue app che non ne hanno bisogno, non modifica nulla alla portabilità del tuo codice e il tuo impegno verso OOP.
Per quanto riguarda l'estensione della classe di domande, mi sembra che tu stia avendo un problema di nomenclatura. Il tuo problema è che se chiami la tua estesa domanda "suggerimento", non ha senso perché il suggerimento non è una domanda. Ma in quel caso, se la tua classe estesa, invece di "suggerimento", fosse chiamata "question_with_hint", allora avrebbe senso, giusto? Lo chiami "suggerimento" solo per renderlo più breve e più utilizzabile. Chiamalo "question_extended" se ti aiuta.

    
risposta data 15.05.2011 - 10:56
fonte
1

Astrazione

Ci sono due modi per aderire al principio Open-Closed. La definizione originale del principio prevedeva che si usasse l'ereditarietà, ma questo ha portato a problemi con grandi alberi di classi ereditate, solo per aggiungere un campo come si sta facendo. Come dice Xananax, potresti renderlo "corretto" nominando la classe QuestionWithHint, ma che cosa fare quando vuoi aggiungere tag, ecc.?

Uncle Bob ha scritto un pezzo nel '96 che descrive un altro approccio, che era diventato popolare da allora , dove si rinomina la classe QuestionWithoutHint, estrarre un'interfaccia Domanda dalla classe QuestionWithoutHint e quindi crearne una nuova chiamata QuestionWithHint, implementando anche Domanda. Puoi quindi sostituirlo con il codice finché non ci saranno più riferimenti a QuestionWithoutHint e sbarazzarti di quella classe, rinominando la nuova in qualcosa di più semplice (QuestionImpl).

Questo è il modo più moderno per aderire all'OCP.

Tuttavia, è mia ferma convinzione che ciò dovrebbe essere fatto solo nei casi in cui la logica viene sostituita, non per aggiungere nuovi campi / proprietà, in cui il codice esistente che utilizza la classe non verrà modificato. Questo è, dopo tutto, il problema che l'OCP mira a risolvere.

    
risposta data 15.05.2011 - 11:51
fonte
1

Non vedo l'OCP che si applica molto alle classi di dominio, ma più alle classi di applicazioni e servizi. Non lasciare che OCP ti impedisca di costruire il dominio in fasi evolutive. Notate invece come emergono i pattern nel modo in cui si usano le librerie esterne (le librerie standard, JDBC, JMS, Servlet, JSP e così via), quindi li spingono in classi di adattatore semplici che diventano sempre più chiuse nel tempo.

    
risposta data 15.05.2011 - 12:30
fonte