Dacă am înțeles corect întrebarea, ați creat un model de domeniu și doriți să scrieți un cartograf obiect-relațional pentru a hărți între înregistrările din baza de date și obiectele domeniului dvs. Cu toate acestea, sunteți preocupat de poluarea modelului dvs. de domeniu cu codul "sanitar" care ar fi necesar pentru a citi și a scrie în câmpurile obiectului.
Dacă faceți un pas înapoi, aveți, în esență, două opțiuni de unde să plasați codul de mapare a datelor - în cadrul clasei de domeniu sau într-o clasă externă de cartografiere.
Prima opțiune este denumită adesea modelul Active Record și are avantajul că fiecare obiect știe să persiste și are suficient acces la structura sa internă pentru a permite efectuarea cartografierii fără a fi necesară expunerea câmpurilor care nu sunt legate de afaceri.
De exemplu
public class User
{
private string name;
private AccountStatus status;
private User()
{
}
public string Name
{
get { return name; }
set { name = value; }
}
public AccountStatus Status
{
get { return status; }
}
public void Activate()
{
status = AccountStatus.Active;
}
public void Suspend()
{
status = AccountStatus.Suspended;
}
public static User GetById(int id)
{
User fetchedUser = new User();
//Lots of database and error-checking code
//omitted for clarity
//...
fetchedUser.name = (string) reader["Name"];
fetchedUser.status = (int)reader["statusCode"] == 0 ? AccountStatus.Suspended : AccountStatus.Active;
return fetchedUser;
}
public static void Save(User user)
{
//Code to save User's internal structure to database
//...
}
}
În acest exemplu, avem un obiect care reprezintă un utilizator cu un nume și un cont de cont. Nu vrem să permitem ca starea să fie setată direct, poate pentru că vrem să verificăm dacă schimbarea este o tranziție valabilă a statutului, deci nu avem setter. Din fericire, codul de cartografiere din metodele GetById și Save static are acces deplin la câmpurile de nume și de stare ale obiectului.
The second option is to have a second class that is responsible for the mapping. This has the advantage of seperating out the different concerns of business logic and persistence which can allow your design to be more testable and flexible. The challenge with this method is how to expose the name and status fields to the external class. Some options are:
1. Use reflection (which has no qualms about digging deep into your object's private parts)
2. Provide specially-named, public setters (De exemplu. prefix them with the word 'Private') and hope no one uses them accidentally
3. If your language suports it, make the setters internal but grant your data mapper module access. De exemplu. use the InternalsVisibleToAttribute in .NET 2.0 onwards or friend functions in C++
Pentru mai multe informații, aș recomanda cartea clasică a lui Martin Fowler "Patterns of Enterprise Architecture"
Cu toate acestea, ca un cuvânt de avertizare, înainte de a merge în jos pe calea de a scrie propriii dvs. cartografiți, aș recomanda cu tărie să vă uitați la utilizarea unui instrument de cartograf obiect relațional (ORM) al unui terț, cum ar fi nHibernate sau Microsoft Entity Framework. Am lucrat la patru proiecte diferite în care, din diverse motive, am scris propriul cartograf și este foarte ușor să pierdem o mulțime de timp menținând și extindând cartograful în loc să scriem cod care să ofere valoare utilizatorului final. Am folosit nHibernate pentru un proiect până acum și, deși are o curbă destul de abruptă de învățare inițial, investiția pe care o puneți pe timpuriu se plătește considerabil.