Ho una classe base (che rappresenta un contenitore del mondo reale pieno di piccole sfere) e alcune classi derivate. Questo funziona bene.
Il mio problema è come fare la loro visualizzazione. Ho un UserControl che visualizza la classe base. La soluzione migliore è avere un UserControl derivato per ciascuna delle classi derivate? O è meglio avere solo uno che lavori per tutti loro?
Modifica:
Apparentemente non ero abbastanza specifico. C'è sempre la stessa apparenza di base: rettangolo con molti cerchi all'interno. La differenza tra le classi è come il contenitore è riempito. Un tipo mette un seme nel mezzo e crea altre sfere in una struttura ad albero - in questo caso le linee di collegamento tra genitori e figli devono essere disegnate.
Generalmente, l'aspetto delle visualizzazioni delle classi dovrebbe essere coerente con alcune specialità per ciascun tipo derivato.Visualizzazione delle classi derivate in C#
risposta
Ho il sospetto che solo tu possa rispondere a questa domanda in modo definitivo. Un'interfaccia utente per una determinata sottoclasse è probabilmente ciò che si desidera, ma se le sottoclassi differiscono solo leggermente, è possibile trovare più semplice aggiungere una logica condizionale in un numero inferiore di controlli utente. Non penso ci sia una risposta esatta a questo.
Difficile dire solo dalla vaga descrizione. Avremmo davvero bisogno di sapere, almeno, quali sono le differenze tra le classi derivate.
In generale, con una conoscenza limitata, mi piacerebbe andare con un UserControl derivato per ogni classe derivata
se le classi di visualizzazione derivata non differiscono tra loro, poi, con tutti i mezzi, utilizzare uno UserControl. Il punto principale qui è ASCIUTTO.
Questo dipende molto dall'aspetto dei display. Se le visualizzazioni delle classi derivate sono molto simili alla classe base, è sufficiente che l'unico UserControl esegua la visualizzazione. OTOH, se ogni classe derivata ha bisogno di visualizzare cose uniche, allora sarà meglio avere un UserControl separato per visualizzare ogni classe derivata. Non posso davvero essere più specifico senza informazioni più specifiche sulle tue lezioni.
MODIFICA: Dalle tue informazioni aggiuntive direi che dovresti avere una classe di visualizzazione di base che disegna il contenitore rettangolare del commom e che ha ottenuto UserControls che gestiscono il disegno del contenuto di ciascun tipo specifico.
Sono d'accordo con la risposta modificata. Chiedi alla tua classe base di fare tutto il disegno e ricava una classe e sovrascrivi quelli che cambiano tra i tipi. Si potrebbe avere un ciclo generico nella classe base che chiama un metodo 'draw next' che si sovrascrive nelle sottoclassi. –
Un approccio al problema sarebbe decomposizione seguendo la prospettiva MVVC:
Avrete bisogno di un UserControl come View.
Un pittore di base, che gestisce il dipinto della "scatola con cerchi in esso" come ViewModel. I pittori derivati implementano diverse logiche di posizionamento degli oggetti e delle loro interconnessioni.
Se l'aspetto dei tuoi oggetti può variare, è necessario che vengano consegnati al pittore come ViewModel possibilmente attraverso il modello dell'adattatore.
Infine, le tue cerchie, i rettangoli e gli elementi associati ad essi sono il Modello.
generale:
View (UserControl) -> ViewModel (pittore + Imbianchini derivati + opporsi ViewModels) -> Modello (cerchio, rettangolo, ecc)
Non capisco appieno il vostro dominio del problema ma penso che tu debba rompere questo ancora un po '. decomponi il tuo modello in parti e scrivi viste per ogni parte, quindi puoi semplicemente collegarle di nuovo.
Scriverei una vista per le sfere, una vista per le linee tra le sfere e una vista per il rettangolo che contiene tutto, quindi ognuno dei modelli sarà responsabile dell'organizzazione e della creazione dei corrispondenti SphereModels e LineModels (e qualsiasi altra cosa hai bisogno) quindi la tua vista principale deve solo essere responsabile della posa di questi nella scatola.
Ricorda sempre preferire la composizione all'eredità! Concentrati su come suddividere il tuo problema in parti più piccole.
buona fortuna
penso che vorrei andare con una classe base Visualizer che ha avuto alcuni metodi protetti per disegnare i cerchi e linee, e forse qualche proprietà per la superficie di disegno (Canvas?) In modo ogni implementazione in grado di calcolare la misura posizioni basate su base, ecc.
La classe di base implementa tutti i metodi di interfaccia/puntelli necessari per renderlo un visualizzatore.
Utilizzare lo schema di strategia nel metodo chiamato IDE quando si suppone che il visualizzatore si disegna da sé ... l'implementazione del metodo potrebbe cancellare la tela, impostare i pennelli e altre cose che devono essere comuni a ogni implementazione, quindi chiama un metodo astratto della classe base che posiziona effettivamente i cerchi/scatole/linee/etc sulla tela.
In questo modo, ogni implementazione specifica deve solo preoccuparsi della logica per posizionare correttamente le cose in base al proprio insieme di regole - tutte le "cose da disegno sulla tela" vengono mantenute nella classe base.
HTH
EDIT: Corretto errore di battitura che possono aver causato confusione, dove ho usato il termine "controllo" quando dire "visualizzatore".
Sembra una situazione con più soluzioni.
Un modo per farlo sarebbe impostare UserControl per chiamare un metodo virtuale nella classe base e quindi sovrascriverlo nelle classi derivate. Nelle classi derivate, puoi semplicemente chiamare l'implementazione di base per impostare inizialmente il frame.
È anche possibile impostarlo per il rendering in livelli (un livello contenitore, livello sfera, livello riga, ecc.) E fare in modo che la classe figlio esegua il rendering di tutti i livelli univoci e determini l'ordine. Questo può essere costoso, ma potrebbe smussare le immagini se la maggior parte dell'immagine rimane uguale.
Un altro è utilizzare i delegati piuttosto che l'ereditarietà, ma questo tende a diventare disordinato. Questa non è generalmente una buona idea a causa delle penalità prestazionali. Tuttavia, ha il vantaggio della flessibilità di runtime. A seconda del resto del codice, con questo modello potresti essere in grado di cambiare gli stili di crescita a metà. Se non ti vedi approfittare di questa flessibilità, ti consiglio comunque di utilizzare un modello diverso.
Indipendentemente dal metodo utilizzato, è consigliabile che la classe di base fornisca le routine di disegno comuni per garantire la coerenza.Le routine nella classe base dovrebbero essere utilizzate dalla maggior parte delle classi figlio, ma non necessariamente tutte. Questo di solito porta a un codice più gestibile (a meno che non si finisca con un file di linea da 10000), meno bug e meno sforzo.
che suonano per me come il modello decorator:
- 1. Riflettere classi derivate in C#
- 2. Modelli C++ e classi derivate
- 3. specializzazione Template e classi derivate in C++
- 4. Copia C++ di due classi derivate
- 5. C# comportamento foreach con classi derivate?
- 6. C++ template fusione con le classi derivate
- 7. C# - serializzazione XML di classi derivate
- 8. Estendere enum nelle classi derivate
- 9. Evento eventi di classe base in classi derivate C#
- 10. Sovrascrivere le costanti nelle classi derivate in C#
- 11. Metodi C++ in classi derivate con parametri diversi
- 12. uguaglianza di prova per le classi derivate in C++
- 13. Prestazioni delle funzioni virtuali chiamate da classi derivate?
- 14. Individuazione delle eccezioni derivate?
- 15. C++ Boost serializzazione serializzazione di classi derivate templated
- 16. Override di membri statici in classi derivate in PHP
- 17. Java classi astratte: Tornando puntatore "this" per le classi derivate
- 18. implementazione della proprietà force su classi derivate
- 19. Scala Play framework classi derivate 2.1
- 20. Utilizzando XmlSerializer per serializzare classi derivate
- 21. Metodi pubblici extra nelle classi derivate?
- 22. Come chiamare i metodi sovrascritto in tutte le classi derivate
- 23. Uso delle classi interne in C#
- 24. WCF DataContract Escludere DataMembers da essere serializzato in classi derivate
- 25. Come funzionano i costruttori di classi derivate in python?
- 26. Conversione del puntatore-puntatore tra classi derivate e di base?
- 27. Confronto di classi derivate in C++ senza fusione dinamica o downcast statico
- 28. Perché devo ri-dichiarare le funzioni sottoposte a override nelle classi derivate in C++?
- 29. Svantaggi della parola chiave "Utilizzo" in C++ applicata alle classi derivate
- 30. Come posso creare dinamicamente classi derivate da una classe base
Stai cercando di vincere un concorso di conteggio jelly-bean? –
Penso che questa sia una questione molto importante nell'ingegneria del software; Mi sono imbattuto in situazioni simili e non so davvero come risolverlo correttamente. È un peccato che tutte le risposte finora abbiano mancato il punto. – Timwi
@James Curran: Sort of. Solo che non ci sono concorrenti e le jelly-bean sono sostituite con microsfere di vetro cavo – Lukas