Если я правильно понял вопрос, вы создали модель предметной области и хотели бы написать объектно-реляционное сопоставление для сопоставления записей в вашей базе данных и объектов вашего домена. Тем не менее, вы обеспокоены загрязнением вашей доменной модели с помощью «слесарного» кода, который был бы необходим для чтения и записи в поля вашего объекта.
Делая шаг назад, у вас, по сути, есть два варианта размещения кода отображения данных - внутри самого класса домена или во внешнем классе отображения.
Первый вариант часто называют шаблоном Active Record и имеет то преимущество, что каждый объект знает, как сохранить себя, и имеет достаточный доступ к своей внутренней структуре, чтобы позволить ему выполнять сопоставление, не раскрывая не связанные с бизнесом поля.
* 1005 например *
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
// ...
}
}
В этом примере у нас есть объект, который представляет пользователя с именем и AccountStatus. Мы не хотим разрешать установку статуса напрямую, возможно, потому что мы хотим проверить, является ли изменение действительным изменением статуса, поэтому у нас нет установщика. К счастью, код отображения в статических методах GetById и Save имеет полный доступ к полям имени и состояния объекта.
Второй вариант - иметь второй класс, отвечающий за отображение. Преимущество этого состоит в том, чтобы отделить различные аспекты бизнес-логики и постоянства, что может сделать ваш проект более тестируемым и гибким. Сложность этого метода заключается в том, как открыть поля name и status для внешнего класса. Некоторые варианты:
1. Используйте рефлексию (которая не задумывается о том, как глубоко копаться в закрытых частях вашего объекта)
2. Предоставьте общедоступные сеттеры со специальными именами (например, добавьте к ним префикс «Private») и надейтесь, что никто не использует их случайно
3. Если ваш язык поддерживает это, сделайте сеттеры внутренними, но предоставьте доступ вашему модулю отображения данных. Например. используйте атрибут InternalsVisibleToAttribute в .NET 2.0 и далее или функции-друзья в C ++
Для получения дополнительной информации я бы порекомендовал классическую книгу Мартина Фаулера «Шаблоны архитектуры предприятия»
Однако, в качестве предупреждения, перед тем, как пойти по пути написания собственных картографических функций, я настоятельно рекомендую рассмотреть использование стороннего инструмента объектного реляционного картографирования (ORM), такого как nHibernate или Microsoft Entity Framework. Я работал над четырьмя различными проектами, где по разным причинам мы написали свой собственный преобразователь, и очень легко тратить много времени на его обслуживание и расширение вместо написания кода, обеспечивающего ценность для конечного пользователя. До сих пор я использовал nHibernate для одного проекта, и, хотя изначально у него довольно крутая кривая обучения, инвестиции, которые вы вложили на раннем этапе, значительно окупаются.