加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

entity-framework – 如何以规则的形式避免使用业务逻辑的贫血域

发布时间:2020-12-14 18:28:22 所属栏目:资源 来源:网络整理
导读:我正在设计一个系统,它有一个简单的实体框架支持的域对象,其中包含我需要根据一系列规则更新的字段 – 我想逐步实现这些规则(以敏捷方式)并且因为我使用EF我对此持怀疑态度将每个规则放入域对象.但是,我想避免编写“程序代码”并使用贫血领域模型.这一切都需
我正在设计一个系统,它有一个简单的实体框架支持的域对象,其中包含我需要根据一系列规则更新的字段 – 我想逐步实现这些规则(以敏捷方式)并且因为我使用EF我对此持怀疑态度将每个规则放入域对象.但是,我想避免编写“程序代码”并使用贫血领域模型.这一切都需要是可测试的.

例如,对象是:

class Employee { 
 private string Name; 
 private float Salary; 
 private float PensionPot;
 private bool _pension;
 private bool _eligibleForPension;

}

我需要构建规则,例如“如果Salary高于100,000且_eligibleForPension为false,则将_eligibleForPension设置为true”和“if _pension为true,然后将_eligibleForPension设置为true”.

有大约20个这样的规则,我正在寻找建议是否应该在Employee类或类似EmployeeRules类中实现?我的第一个想法是为从“规则”继承的每个规则创建一个单独的类,然后将每个规则应用于Employee类,可能使用Visitor模式但我必须将所有字段暴露给规则才能执行此操作感觉不对.虽然在Employee类上有每个规则也感觉不对.这将如何实施?

第二个问题是实际的Employees是支持DB的实体框架实体,因此我不乐意为这些“实体”添加逻辑 – 特别是当我需要模拟对象以对每个规则进行单元测试时.如果他们有我在相同对象上测试的规则,我怎么能嘲笑他们?

我一直在考虑使用AutoMapper在应用规则之前转换为更简单的域对象,但之后需要自己管理对字段的更新.对此也有任何建议吗?

解决方法

一种方法是使规则成为Employee的内部类.这种方法的好处是字段可以保持私密.此外,可以通过Employee类本身强制执行规则,确保在需要时始终调用它们:
class Employee
{
    string id;
    string name;
    float salary;
    float pensionPot;
    bool pension;
    bool eligibleForPension;

    public void ChangeSalary(float salary)
    {
        this.salary = salary;
        ApplyRules();
    }

    public void MakeEligibleForPension()
    {
        this.eligibleForPension = true;
        ApplyRules(); // may or may not be needed
    }

    void ApplyRules()
    {
        rules.ForEach(rule => rule.Apply(this));
    }

    readonly static List<IEmployeeRule> rules;

    static Employee()
    {
        rules = new List<IEmployeeRule>
        {
            new SalaryBasedPensionEligibilityRule()
        };
    }

    interface IEmployeeRule
    {
        void Apply(Employee employee);
    }

    class SalaryBasedPensionEligibilityRule : IEmployeeRule
    {
        public void Apply(Employee employee)
        {
            if (employee.salary > 100000 && !employee.eligibleForPension)
            {
                employee.MakeEligibleForPension();
            }
        }
    }
}

这里的一个问题是Employee类必须包含所有规则实现.这不是一个主要问题,因为规则体现了与员工养老金相关的业务逻辑,因此它们确实属于一起.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读