2010-04-07 9 views
5

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:

  1. Ci saranno i tipi di punti che è necessario conoscere tutti gli altri punti presenti nella classe GraphicObject per sapere come disegnare se stessi.
  2. 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?

risposta

4

vorrei fare come lei ha suggerito e rendere ogni punto di responsabile di disegno stesso, passando per la serie di altri punti ad esso:

interface ICanDraw { 
    void Draw(ArrayList<Point> allPoints); 
} 

public abstract class Point : ICanDraw { 
    ... 
} 

public PoniePoint : Point { 
    public void Draw(ArrayList<Point> allPoints) { 
     // do drawing logic here 
    } 
} 

Per la vostra GraphicMaker:

public void DoDrawing() { 
    foreach (Point point in points) { 
     point.Draw(points); 
    } 
} 

(My Java è un po 'arrugginito, quindi non è possibile che il 100% sintatticamente corregga Java, ma penso che trasmetta il mio suggerimento).

+0

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. –

+1

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. –

+3

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. –

3

È corretto che ogni sottoclasse di Punto debba avere il proprio metodo di disegno che sostituisce quello della classe Punto base.

Il metodo di disegno dovrebbe fare riferimento all'oggetto grafico, che dovrebbe avere metodi/proprietà pubbliche per tutto ciò che deve essere usato nei metodi di disegno del punto, incluso l'elenco di punti se questa è una delle cose i metodi di disegno hanno bisogno.

Perché sei preoccupato di creare metodi pubblici per la classe grafica? Una volta che il codice cresce, alcuni metodi extra visibili sono molto meno confusi di un metodo enorme che fa tutto.

+0

Sì, penso che tu abbia ragione. Avere alcune proprietà/metodi pubblici è definitivamente il modo di andare qui. –

Problemi correlati