0

想象一个具有许多属性的假设对象:

伪代码:

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

现在用户输入值,对象获取它们:

姓名:Shelby Lake
出生日期:6/19/1991
身高:63
GPA:5.6
公民身份:United States

具有所有业务逻辑的层可以验证它:

BusinessLayer.ValidateStudent(student);

例如,在这个例子中,它可以抛出一个异常:

ClientException
GPA cannot exceed 4.00 (5.60)

好的。但并非用户输入的所有内容都可以“放入”对象中:

姓名:Shelby Lake
出生日期:19 years ago
身高:5'3
GPA:n/a
公民身份:n/a

事实上,我们的用户可以在商业决策中输入更友好的值。同时有全局业务规则决定某些输入何时有效,例如

GPA:(5.6 无效)
GPA:(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
日期自由形式:19 years ago
身高自由形式:5'3
GPA:4.6 公民身份:n/a

BusinessLayer.ValidateStudent(student);

业务层可以将自由格式的值转换为规范值,报告任何错误:

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

但这似乎是一个丑陋的答案,我什至不想考虑。

用业务规则解析用户输入的企业方法是什么?

4

1 回答 1

2

当用户输入的数据与模型表示数据的方式显着不同时,我采用的一种方法是为视图模型使用特定的类,并在此类中提供帮助方法以将该视图模型转换为适当的域对象:

 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 而不是域对象进行验证,并保证您的模型不需要适应无效数据,这使它们能够专注于代表您的域的真正目的,而不是不断地防范无效数据。

此外,当您拥有转化为深度对象图的“平面”用户体验时,这种方法变得非常有用。

于 2010-08-16T19:06:12.997 回答