Sto combattendo con questo problema di progettazione OOP. Prendi queste classi base, ad esempio:
class Database
{
public string ConnectionString { get; set; }
public Table MyTable { get; set; }
}
class Table
{
public string Name { get; set; }
}
Questo esempio è troppo semplificato per concentrarsi solo sulla domanda in questione.
Se volevo aggiungere una logica che avrebbe ottenere il conteggio della riga Table
, penseresti che naturalmente appartenga alla classe Table
:
class Table
{
public string Name { get; set; }
public int GetRowCount() { ... }
}
Il problema è che, per ottenere il conteggio delle righe, è necessario che si verifichi una connessione al database . Non è un grosso problema, ma la classe Table
non ha modo di recuperare la proprietà Database.ConnectionString
per connettersi effettivamente per ottenere il conteggio delle righe della tabella specifica.
Vedo alcune opzioni qui e nessuno di loro sembra davvero un ottimo approccio.
Mantieni la logica fuori dagli oggetti figlio
In questo caso, la logica GetRowCount()
dovrebbe vivere nell'oggetto padre. Qualcosa del genere:
class Database
{
public string ConnectionString { get; set; }
public Table MyTable { get; set; }
public int GetRowCount(Table table) { ... }
}
class Table
{
public string Name { get; set; }
}
La classe Table
è ora "stupida" per la logica del conteggio delle righe, che non è del tutto una cosa negativa, ma ora non c'è modo di avere un membro nella classe Table
per archiviare o recuperare dati direttamente correlati alla classe Table
.
Avere un riferimento all'oggetto padre nell'oggetto Bambino
Questo mi piace anche meno dell'approccio di cui sopra. In questo caso, sarebbe simile a qualcosa del tipo:
class Database
{
public string ConnectionString { get; set; }
public Table MyTable { get; set; }
}
class Table
{
public string Name { get; set; }
public Database Parent { get; set; }
public int GetRowCount() { ... }
}
Certo, Table.GetRowCount()
può creare un riferimento a Table.Parent.ConnectionString
, ma sembra solo una ricorsione inutile e ... sciatta.
L'Explicit trasmette i dati richiesti intorno
Non mi piace neanche questo, ma se l'implementazione di Table.GetRowCount()
richiede che la stringa di connessione sia passata a questa, questa logica potrebbe vivere nella classe Table
, ma ora c'è una mancanza di DRY e una perdita di Database
di dati nell'implementazione Table
:
class Database
{
public string ConnectionString { get; set; }
public Table MyTable { get; set; }
}
class Table
{
public string Name { get; set; }
public int GetRowCount(string connectionString) { ... }
}
Per non parlare del fatto che ciò potrebbe portare a problemi di logica complicati, immagino.
Come viene fatto in genere e qual è l'approccio migliore qui? Voglio che la logica del conteggio delle righe vada dove è naturale, con la classe Table
. Ma la logica e i dati dipendono da un membro (la stringa di connessione) che vive naturalmente nella classe Database
.