У меня есть персистентность неосведомленная модель предметной области, которая использует абстрактные репозитории для загрузки объектов области. Конкретная реализация моих репозиториев (уровень доступа к данным (DAL)) использует платформу объекта для выборки данных из базы данных SQL-сервера. База данных имеет ограничения длины на большое количество ее varchar столбцов. Теперь предположите, что у меня есть следующий доменный класс:
public class Case
{
public Case(int id, string text)
{
this.Id = id;
this.Text = text;
}
public int Id { get; private set; }
public string Text { get; set; }
}
И абстрактный репозиторий, определенный следующим образом:
public abstract class CaseRepository
{
public abstract void CreateCase(Case item);
public abstract Case GetCaseById(int id);
}
[text]
столбец таблицы в sqlserver определяется как nvarchar(100)
Теперь я знаю, что упомянул что мой доменный класс (Case
) была неосведомленная персистентность, тем не менее, я чувствую, что неправильно, что это допускает значения text
параметр, который не может в конечном счете быть сохранен моей конкретной реализацией репозитория, потому что платформа объекта выдаст исключение при присвоении text
свойство к платформе объекта генерировало класс, когда это - дольше, чем 100 символов. Таким образом, я решил, что хочу проверить это ограничение в модель предметной области, потому что это позволяет мне проверять законность данных прежде, чем попытаться передать его на DAL и таким образом делать сообщение об ошибке более центральным к объекту области. Я предполагаю, что Вы могли утверждать, что я мог просто проверить ограничение в своего конструктора и в метод set свойства, но так как у меня есть сотни классов, что у всех есть подобные ограничения, я хотел более универсальный способ решить проблему
Теперь, вещью, которую я придумал, является названный класс ConstrainedString
, определенный следующим образом:
public abstract class ConstrainedString
{
private string textValue;
public ConstrainedString(uint maxLength, string textValue)
{
if (textValue == null) throw new ArgumentNullException("textValue");
if (textValue.Length > maxLength)
throw new ArgumentException("textValue may not be longer than maxLength", "textValue");
this.textValue = textValue;
this.MaxLength = maxLength;
}
public uint MaxLength { get; private set; }
public string Value
{
get
{
return this.textValue;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Length > this.MaxLength) throw new ArgumentException("value cannot be longer than MaxLength", "value");
this.textValue = value;
}
}
}
Кроме того, у меня есть реализация ConstrainedString
названный String100
:
public class String100 : ConstrainedString
{
public String100(string textValue) : base(100, textValue) { }
}
Таким образом ведя к другой реализации Case
это было бы похоже на это:
public class Case
{
public Case(int id, String100 text)
{
this.Id = id;
this.Text = text;
}
public int Id { get; private set; }
public String100 Text { get; set; }
}
Теперь, мой вопрос; я пропускаю некоторые встроенные классы или некоторый другой подход, который я мог использовать вместо этого? Или действительно ли это - разумный подход?
Любые комментарии и предложения приветствуются.
Заранее спасибо
Я считаю, что ваша проверка должна находиться в вашей модели домена. Ограничения на ваши поля напрямую представляют некоторую бизнес-логику. В конце концов, вы должны подтвердить, прежде чем продолжать настаивать.
Я думаю, что это зависит от многих факторов (а также некоторых личных предпочтений). Иногда ограничение должно образовывать часть объекта домена - например, с номерами социального страхования / номерами паспорта ... - они обычно имеют фиксированную длину и не могут варьироваться в качестве правила домена - не правило настойчивости данных (хотя вы можете ограничить действие DB также).
Некоторые предпочитают не иметь таких чеков в модели их домена, а вместо этого есть что-то вроде атрибута проверки в свойстве, которое можно проверить и выполнять внешние из объекта домена отдельным валидатором.
Проблема, которую вы могли бы иметь с вашим методом (хотя не сложно обойти), получает любой ORM / MAPPER - если вы используете один - знать, как сопоставить строку в / из БД в соответствии с вашим ограничением.
ConstedString может не охватить проблему объекта домена, имеющую дополнительную информацию о ограничении, так как может потребоваться построить ограниченный настроек
Если вы измените ограничения дела, имеет смысл создать новый - вы изменили контракт, и старый код больше не будет знать, соответствует ли он требованиям или нет.
Вместо того, чтобы беспокоиться о том, что ваш репозиторий позволит или не разрешит, определите, что вы разрешите в своем классе, и убедитесь, что вы нашли способ работать с любым репозиторием, на которое вы переходите в будущее. Вы владеете своим API, а ваши зависимости - нет.