在哪里存储值,以便传输到业务层?

时间:2010-08-16 18:59:52

标签: model-view-controller user-input business-logic business-rules

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

伪代码:

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
BirthdateFreeform:19 years ago
高度自由:5'3
GPA:4.6 公民身份:n/a

BusinessLayer.ValidateStudent(student);

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

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

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

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

1 个答案:

答案 0 :(得分: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而不是域对象进行验证,并保证您的模型不需要容纳无效数据,这样他们就可以专注于表示域的真实目的,而不是经常防范无效数据。

此外,当您具有转换为深层对象图的“平坦”用户体验时,此方法将变得非常有用。