Siccome ho risposto a domande relative alla progettazione orientata agli oggetti e a come ridurre la quantità di classi per assicurarmi che non ci sia un sacco di "confusione di classe" e ripetizione del codice, ho iniziato a dubitare di come molto incapsulamento è troppo incapsulamento e per lo stesso motivo quanto incapsulamento non è abbastanza incapsulamento.
Ecco uno scenario specifico. Uno dei più dolorosi, che ho già incontrato alcune volte, è quando si cerca di recuperare alcuni pezzi di dati simili dal database e, di conseguenza, anche gli oggetti e gli archivi di riga sembrano molto simili.
Questo fa sorgere una domanda su quanto dovrebbe incapsulare. Immagino che per gli oggetti entità si possa creare una classe base, ma per quanto riguarda i repository?
La maggior parte del codice di mappatura sarà simile, ma hai intenzione di mettere metà della mappatura nella classe base e metà della sottoclassi? Non che non puoi, ma per me personalmente è un odore di codice, nel senso che la tua classe base dovrebbe facilitare la creazione delle sue classi derivate, ma non aiutarle con la loro implementazione del metodo. Dovrebbe consentire loro di sovrascrivere i metodi, ma non dare loro metà della logica di mappatura e quindi lasciarli implementare il resto.
Preferiresti invece separare completamente i repository anche se fossero un po 'simili nella mappatura dei dati (gli oggetti entità sarebbero diversi per ciascun repository) o proverai a classarne una parte?
Fondamentalmente la mia lotta è questa:
Would you rather let each repository encapsulate all that it needs for itself even if some of it might be similar to other repositories?
o
Would you rather base class it by getting rid of the duplication and as a result have that strange design where a base class provides half the logic and the subclasses take care of the rest?
Esempio:
public class RepositoryA
{
private EntityObjectA load()
{
// load from db by calling a stored procedure
// once loaded we do mapping
}
}
public class RepositoryB
{
private EntityObjectB load()
{
// load from db by calling a stored procedure
// once loaded we do mapping
}
}
public class RepositoryC
{
private EntityObjectC load()
{
// load from db by calling a stored procedure
// once loaded we do mapping
}
}
public class EntityObjectA
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
}
public class EntityObjectB
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
public string field4 { get; set; }
public string field5 { get; set; }
}
public class EntityObjectC
{
public string field1 { get; set; }
public string field2 { get; set; }
}
Ora creerai una base di partenza come EntityObjectBase?
Che posso ancora capire ma per quanto riguarda i repository?
Voglio dire che puoi praticamente vedere la mappatura sarà abbastanza simile ma vale la pena provare a combinarli?
Quanto vai lontano con l'incapsulamento perché in questo caso ci sarà qualche ripetizione del codice se non lo facciamo, ma se lo facciamo otteniamo un tipo strano di design.