想象一个具有许多属性的假设对象:
伪代码:
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")
但这似乎是一个丑陋的答案,我甚至不想考虑它。
使用业务规则解析用户输入的企业方法是什么?
答案 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而不是域对象进行验证,并保证您的模型不需要容纳无效数据,这样他们就可以专注于表示域的真实目的,而不是经常防范无效数据。
此外,当您具有转换为深层对象图的“平坦”用户体验时,此方法将变得非常有用。