Я видел, как некоторые объектно-ориентированные эксперты советуют, чтобы доменные объекты (POCO) были неизменяемыми.
То есть их состояние должно быть полностью определено при создании, а для изменения состояния должно потребоваться создание совершенно нового экземпляра.
Но, скажем, я сохраняю реляционную БД с помощью ORM - как определить, какие свойства сохранить, и как восстановить объект домена на основе данных в базе данных?
Например, скажем, я хочу записать этот объект в базу данных:
class User
{
private string _emailAddress;
public User(string emailAddress, string password)
{
// ... generate hash & seed
_emailAddress = emailAddress;
}
public string PasswordHash { get; private set; }
public string PasswordSeed { get; private set; }
public bool ValidatePassword(string password)
{
// validate it against the stored hash
}
}
В приведенном выше примере я хочу сохранить состояние объекта и получить его позже. Это означает хранение PasswordHash, PasswordSeed и EmailAddress.
Но структура класса не позволяет мне сделать это.
PasswordHash и PasswordSeed - я могу их сохранить, но что произойдет, когда я захочу прочитать их обратно из базы данных и восстановить объект? Там нет параметров конструктора, чтобы передать их, и я даже не могу построить объект без них, потому что должен быть указан «пароль», и я не знаю, какой был оригинальный пароль. Я не могу установить свойства «PasswordHash» или «PasswordSeed», потому что они «закрытый набор».
EmailAddress - я не могу сохранить его, потому что, хотя он является частью состояния объекта, он помечен как частный и недоступен для внутреннего доступа.
Да, я могу просто сделать все свойства объекта публичными и читать / писать. Но тогда где же моя инкапсуляция и неизменность?
Видите, я хотел сохранить пароль в виде хэша / семени и скрыть адрес электронной почты по причине. Я хотел навязать определенный рабочий процесс объектам моего домена.
Но когда дело доходит до их хранения, мне нужно отменить все эти ограничения и превратить мои доменные объекты в хранилища немых ключей / значений без ограничений.
Основная проблема, по-видимому, заключается в том, что реляционные базы данных не имеют понятия инкапсуляции. Каждый столбец в таблице является «общедоступным», а каждое значение - «изменяемым».
Значит ли это, что мне нужно полностью исключить реляционное отображение, если я хочу иметь неизменную модель предметной области? Или есть какая-то известная стратегия для обхода этого, о которой я просто еще не знаю?