Sto progettando un'applicazione che mi consentirà di disegnare alcune funzioni su un grafico. Ogni funzione verrà disegnata da una serie di punti che passerò a questa classe grafica.Progettare una classe in modo che non diventi un "oggetto Dio"
Esistono diversi tipi di punti, tutti ereditati da una classe MyPoint. Per alcuni tipi di punti sarà solo stamparli sullo schermo così come sono, altri possono essere ignorati, altri aggiunti, quindi c'è una sorta di logica ad essi associata che può diventare complessa.
Come disegnare effettivamente la grafica non è il problema principale qui. Quello che mi infastidisce è come rendere la logica del codice tale che questa classe di GraphicMaker non diventi il cosiddetto oggetto di Dio.
Sarebbe facile fare qualcosa di simile:
class GraphicMaker {
ArrayList<Point> points = new ArrayList<Point>();
public void AddPoint(Point point) {
points.add(point);
}
public void DoDrawing() {
foreach (Point point in points) {
if (point is PointA) {
//some logic here
else if (point is PointXYZ) {
//...etc
}
}
}
}
Come faresti qualcosa di simile? Ho la sensazione che il modo corretto sarebbe quello di mettere la logica di disegno su ogni oggetto Point (quindi ogni classe bambino da Point saprebbe come disegnare se stesso), ma due problemi sorgono:
- Ci saranno i tipi di punti che è necessario conoscere tutti gli altri punti presenti nella classe GraphicObject per sapere come disegnare se stessi.
- Posso rendere molti dei metodi/proprietà dalla classe Graphic pubblica, in modo che tutti i punti abbiano un riferimento alla classe Graphic e possano fare tutta la loro logica come vogliono, ma non è un grosso prezzo per pagare per non voler avere una lezione di Dio?
Aha! Non avevo pensato che la classe GraphicObject passasse la lista dei punti come argomento al metodo Draw() di Point. Sembra una buona idea. Anche se non sono ancora sicuro che non sia il caso di rendere pubbliche tutte le proprietà possibilmente rilevanti nella classe GraphicObject, come forse in futuro avrò bisogno della mia logica di disegno dei punti, non solo la lista di tutti i punti, ma qualche altra cosa. Se ho passato la lista invece di avere proprietà pubbliche, dovrei aggiungere nuovi parametri ai metodi Draw() del punto. –
Dipende molto da come funziona GraphicsObject, ma penso che preferirei non passarlo nel metodo Draw (potrei sbagliarmi, è molto contestuale e non ho il contesto completo).Se si scopre che è necessario un sottoinsieme di informazioni che GraphicsObject può fornire, oltre a tutti i Punti, vorrei prendere in considerazione la creazione di una classe esclusivamente allo scopo di passare al metodo Draw che contiene un elenco di punti e gli elementi aggiuntivi da GraphicsObject che si bisogno. Ciò mantiene la singola repository e la separazione delle preoccupazioni. TUTTAVIA: se GraphicsObject riguarda il disegno, passarlo. –
Dai un'occhiata ai sistemi esistenti per l'ispirazione. In Swing, ogni componente ha il proprio paint() che riceve un oggetto Grapics. L'approccio Contenitore/Layout/Componente consente ad alcuni componenti di influenzare altri componenti (contenuti). Tuttavia, non avrei comunque passato la lista a Point's Draw. Aggiungerei una query a GraphicsObject che restituisce un elenco di altri punti. Come i punti con un certo tipo, a una certa distanza, lo stesso colore, ecc. –