Ограничение длины строки в доменных классах - PullRequest
6 голосов
/ 26 января 2010

У меня есть постоянная модель невежественного домена, которая использует абстрактные репозитории для загрузки объектов домена. Конкретная реализация моих репозиториев (уровень доступа к данным (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 и, таким образом, сделать отчеты об ошибках более ориентированными на объект домена. Я думаю, вы могли бы утверждать, что я мог бы просто проверить ограничение в моем конструкторе и в установщике свойств, но так как у меня есть сотни классов, которые имеют схожие ограничения, я хотел более общий способ решения проблемы

Теперь, что я придумал, это класс с именем 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; }
}

Теперь мой вопрос: Я пропускаю некоторые встроенные классы или какой-то другой подход, который я мог бы использовать вместо этого? Или это разумный подход?

Любые комментарии и предложения приветствуются.

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 17 февраля 2010

Я считаю, что ваша проверка должна соответствовать модели вашего домена. Ограничения на ваши поля напрямую представляют некоторую бизнес-логику. В конечном счете, вам все равно нужно подтвердить, прежде чем продолжать.

0 голосов
/ 17 февраля 2010

Если вы измените ограничения кейса, имеет смысл создать новый - вы изменили контракт, и старый код больше не будет знать, соответствует ли он требованиям или нет.

Вместо того, чтобы беспокоиться о том, что разрешит или запретит ваш репозиторий, определите, что вы разрешите в вашем классе, и убедитесь, что вы найдете способ работы с любым репозиторием, на который вы изменили, будущее. Вы владеете своим API - вашими зависимостями нет.

0 голосов
/ 26 января 2010

Я думаю, что это зависит от многих факторов (а также от некоторых личных предпочтений). Иногда ограничение должно быть частью объекта домена - например, с номерами социального страхования / номерами паспортов ... - они обычно имеют фиксированную длину и не могут изменяться как правило домена - не правило сохранения данных (хотя вы можете ограничить БД как хорошо).

Некоторые предпочитают, чтобы такого рода проверки не проводились в их доменной модели, и вместо этого имеют что-то вроде атрибута валидации в свойстве, которое может проверяться и выполняться внешним от объекта домена отдельным валидатором.

Проблема, с которой вы можете столкнуться при работе с вашим методом (хотя это и не сложно обойти), заключается в том, чтобы получить любой ORM / Mapper - если вы его используете - чтобы узнать, как отобразить строку в / из БД в ConstrainedString. 1005 *

ConstrainedString может не обойти проблему объекта домена, имеющего дополнительную информацию об ограничении, поскольку может потребоваться создать ConstrainedString

...