Should I pass the Graphics to the Draw() function?
Bene, quando ho visto questo disegno, la prima cosa che mi è venuta in mente è stata "perché diamine il TextBlock
ha un attributo Graphics?" Non dovrebbe essere possibile disegnare lo stesso blocco su due diversi contesti grafici ? L'oggetto TextBlock
non ha una durata che può essere più lunga della durata dell'oggetto Graphics
? "
Quindi la mia risposta è si - non ha senso per me not avere un parametro Graphics nella funzione Draw
. Ciò implicherà di passare il parametro Graphics
nel metodo DrawBlocks
di Page
, e qualche altro metodo nel tuo Section
, ovviamente, ma probabilmente è la progettazione corretta.
Infatti, quando il tuo TextBlock
ha più di una mezza dozzina di metodi privati, tutti chiamati direttamente o indirettamente da Draw
, e tutti usano lo stesso oggetto Graphics
, potrebbe essere più conveniente Graphics
oggetto passato dal metodo Draw
in una variabile membro, quindi non è necessario avere lo stesso parametro Graphics
in tutti questi metodi. Quindi mantenere questo attributo come membro potrebbe avere senso (ma questo non può essere decifrato dalla piccola parte della classe di blocchi di testo che vediamo nel modello corrente). E se decidi di mantenere questo attributo, assicurati di aggiungere un commento quando questo attributo è impostato e per quanto tempo è valido. Il codice sarà quindi simile a
void Draw(Graphics g)
{
graphics=g;
// ...
// call some members depending on "graphics"
// ...
graphics=null; // just in case, to avoid accessing an invalid graphics object
}
In alternativa, potresti considerare di introdurre una classe helper TextBlockDrawer
, che ottiene l'oggetto Graphics
e il TextBlock
passato come parametro costruttore e incapsula l'intero processo di disegno. In questo modo, non avrai più bisogno di un membro Graphics
nella tua classe TextBlock
, solo in TextBlockDrawer
e questo attributo può essere inizializzato nel costruttore di quella classe. Questo design crea anche una migliore separazione tra i dati ( TextBlock
) e il processo di disegno. Il codice risultante sarà simile al seguente:
class TextBlock
{
public void Draw(Graphics g)
{
var tbDrawer = new TextBlockDrawer(this,g);
tbDrawer.Draw();
}
}
oppure, omettendo completamente il metodo Draw
in TextBlock
e riutilizzando TextBlockDrawer for different text blocks
:
class Page
{
// ...
public void DrawBlocks(Graphics g)
{
var tbDrawer = new TextBlockDrawer(g);
foreach(var tb in MyTextBlocks())
tbDrawer.Draw(tb);
}
}