Где хранить ценности, для транспортировки на бизнес-уровень? - PullRequest
0 голосов
/ 16 августа 2010

Представьте себе гипотетический объект с рядом атрибутов:

псевдокод:

class Student
{
   Name: String;
   Birthdate: DateTime;
   Height: int; //inches
   GPA: float; //"Grade Point Average"
   Citizenship: string;
}

Теперь пользователь вводит значения, а объект их получает:

Имя: Shelby Lake
Дата рождения: 6/19/1991
Высота: 63
Средний балл: 5.6
Гражданство: United States

И слой со всей бизнес-логикой может проверить его:

BusinessLayer.ValidateStudent(student);

В этом примере он может, например, выдать исключение:

ClientException
GPA cannot exceed 4.00 (5.60)

Хорошо, хорошо. Но не все, что вводит пользователь, может «вписаться» в объект:

Имя: Shelby Lake
Дата рождения: 19 years ago
Высота: 5'3
Средний балл: n/a
Гражданство: n/a

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

GPA: 5.6 (недействительно)
Средний балл: n/a (действительный)
Гражданство: n/a (действует)
Гражданство: (недействительно)
Высота: tall (неверно)
Высота: 5'3 (действует)

Моя проблема в том, где мне хранить эти string значения, поскольку я не могу хранить их только в объекте. Им нужно добраться до бизнес-уровня, который знает, как анализировать введенный текст в значения.

Моя первая мысль - сменить класс:

class Student
{
   Name: String;
   Birthdate: DateTime;
   BirthdateFreeForm: string;
   Height: int; //inches
   HeightFreeform: string;
   GPA: float; //"Grade Point Average"
   GPAFreeform: string;
   Citizenship: string;
}

Это позволяет отправлять больше произвольных значений на бизнес-уровень:

Имя: Shelby Lake
Дата рожденияFreeform: 19 years ago
HeightFreeform: 5'3
Средний балл 4.6 Гражданство: n/a

BusinessLayer.ValidateStudent(student);

А бизнес-уровень может преобразовывать значения произвольной формы в канонические значения, сообщая о любых ошибках:

ClientException
Country of citizenship must be entered ("n/a")

Но это кажется таким уродливым ответом, что я даже не хочу его рассматривать.

Каков корпоративный способ для сопоставления ввода пользователя с бизнес-правилами?

1 Ответ

2 голосов
/ 16 августа 2010

Один из подходов, который я использовал, когда данные, введенные пользователем, значительно отличаются от способа представления данных в модели, заключается в использовании определенного класса для модели представления и предоставлении вспомогательных методов в этом классе для преобразования этой модели представления в надлежащийобъект предметной области:

 class StudentViewModel {
    StudentViewModel(Student s) {
       // map the properties of Student to the appropriate view model 
       // properties.
    }

    StudentViewModel() {
       // use this for creating a new student.
    }

    Name: string
    Height: string
    GPA: string
    // etc.

    Student GetUpdatedStudent() {
        // map your view model properties to the Student class 
        // and return an updated Student.
    }
 }

Этот подход чрезвычайно гибок, хотя требуется дополнительная работа.Вы можете выполнить проверку непосредственно по ViewModel, а не по объекту домена, и быть уверенным, что вашим моделям не нужно приспосабливаться к недействительным данным, что позволяет им сосредоточиться на своей истинной цели представления вашего домена, а не на постоянной защите от недействительных данных.

Кроме того, этот подход становится невероятно полезным, когда у вас есть «плоский» пользовательский опыт, который переводится в глубокий объектный граф.

...