遵循 CQRS(命令查询职责分离)的概念,我在我的 MVC 应用程序中直接引用 DAL,并通过 ViewModel 进行所有读取。然而,我的一位同事问我,当读取时必须应用任何业务逻辑时,你会怎么做。例如,如果您需要在如下场景中计算百分比值:
//Employee domain object
class Employee
{
string EmpName;
Single Wages;
}
//Constant declared in some utility class. This could be stored in DB also.
const Single Tax = 15;
//View Model for the Employee Screen
class EmployeeViewModel
{
string EmpName;
Single GrossWages;
Single NetWages;
}
// Read Facade defined in the DAL
class ReadModel
{
List<EmployeeViewModel> GetEmployeeList()
{
List<EmployeeViewModel> empList = new List<EmployeeViewModel>;
string query = "SELECT EMP_NAME, WAGES FROM EMPLOYEE";
...
..
while(reader.Read())
{
empList.Add(
new EmployeeViewModel
{
EmpName = reader["EMP_NAME"],
GrossWages = reader["WAGES"],
NetWages = reader["WAGES"] - (reader["WAGES"]*Tax)/100 /*We could call a function here but since we are not using the business layer, the function will be defined in the DAL layer*/
}
);
}
}
}
在上面的示例中,在 DAL 层中发生的读取期间发生了计算。我们本可以创建一个函数来进行计算,但是由于我们已经绕过业务层进行读取,因此该函数将位于 DAL 中。更糟糕的是,如果 Tax 的值存储在数据库中,有人可能会直接在存储过程中的数据库中执行此操作。因此,我们在其他层中存在潜在的业务逻辑泄漏。
您可能会说为什么不在执行命令时将计算值存储在列中。所以让我们稍微改变一下场景。假设您在具有当前税率的报告中显示员工的潜在净工资,而工资尚未支付。
您将如何在 CQRS 中处理此问题?