业务规则分为两类 [英] Business Rule Split among two classes

查看:187
本文介绍了业务规则分为两类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下业务规则的项目分配域

I have a project allocation domain with the following business rules


  1. 当新员工被分配到一个项目时,总支出应该不超过预算金额。

  2. 对于员工,总分配百分比不应超过100%

我创建了如下所示的实体,在 C#中创建。

I have created entities as shown below created in C#.

QUESTION

分配逻辑分为两类 - Project和Employee... List< Allocation> 作为参数传递给Allocate方法,而不是添加为类的属性...是正确的方法,还是需要在这两个类中添加列表< Allocation> 作为属性?

The Allocate logic is split across two classes – Project and Employee..The List<Allocation> is passed as a parameter to the Allocate method rather than adding as property of the class... Is it correct approach or do I need to add List<Allocation> as property in these two classes?

注意:

数据库

作用

代码

项目

 public class Project
    {
        public int ProjectID { get; set; }
        public int BudgetAmount { get; set; }
        public string ProjectName { get; set; }

        public void Allocate(Role newRole, int newPercentage, Employee newEmployee, List<Allocation> existingAllocationsInProject)
        {
            int currentTotalExpenditure = 0;
            if (existingAllocationsInProject != null)
            {
                foreach (Allocation alloc in existingAllocationsInProject)
                {
                    int allocationExpenditure = alloc.Role.BillRate * alloc.PercentageAllocation / 100;
                    currentTotalExpenditure = currentTotalExpenditure + allocationExpenditure;
                }
            }

            int newAllocationExpenditure = newRole.BillRate * newPercentage / 100;
            if (currentTotalExpenditure + newAllocationExpenditure <= BudgetAmount)
            {
                List<Allocation> existingAllocationsOfEmployee = GetAllocationsForEmployee(newEmployee.EmployeeID);
                bool isValidAllocation= newEmployee.Allocate(newRole, newPercentage, existingAllocationsOfEmployee);

                if (isValidAllocation)
                {
                    //Do allocation
                }
                else
                {
                    throw new Exception("Employee is not avaiable for allocation");
                }

            }
            else
            {
                throw new Exception("Budget Exceeded");
            }

        }
    }

Employee

public class Employee
{
    public int EmployeeID { get; set; }
    public string EmployeeName { get; set; }


    public bool Allocate(Role newRole, int newPercentage, List<Allocation> existingAllocationsOfEmployee)
    {
        int currentTotalAllocation = 0;
        if (existingAllocationsOfEmployee != null)
        {
            foreach (Allocation alloc in existingAllocationsOfEmployee)
            {
                currentTotalAllocation = currentTotalAllocation + alloc.PercentageAllocation;
            }
        }

        if (currentTotalAllocation + newPercentage <= 100)
        {
            return true;
        }

        return false;
    }

    }

参考

以下是存储库模式,不含一个ORM


有什么行为需要客户列出订单?当您更多地考虑到您的域的行为(即在什么时候需要什么数据)时,您可以根据用例来建模聚合,事情变得更清晰,更容易,因为只能更改一小组对象的跟踪在总共边界。

What behaviour is there that requires the customer to have a list of orders? When you give more thought to the behaviour of your domain (i.e. what data is required at what point) you can model your aggregates based around use cases and things become much clearer and much easier as you are only change tracking for a small set of objects in the aggregate boundary.

我怀疑客户应该是没有订单列表的单独的合并,而订单应该是具有订单行列表的聚合。如果您需要为客户执行每个订单的操作,请使用orderRepository.GetOrdersForCustomer(customerID);做出改变然后使用orderRespository.Save(order);

I suspect that Customer should be a separate aggregate without a list of orders, and Order should be an aggregate with a list of order lines. If you need to perform operations on each order for a customer then use orderRepository.GetOrdersForCustomer(customerID); make your changes then use orderRespository.Save(order);


推荐答案

我有几个意见:

分配逻辑是正确的事情

考虑将分配逻辑移到服务类例如ProjectService和EmployeeService,所以域模型可以是免费的。

Consider to move the allocate logic to service classes e.g. ProjectService and EmployeeService, so the domain models can be logic free

考虑添加一个新的AllocationService类来操纵分配。

Consider to add a new AllocationService class to manipulate the allocations.

public void Allocate(Project project, Role role, Employee employee, int percentage)
{
      // Fetch allocation from allocation repository
      var allocations = _allocationRepository.GetAllocations(project.Id);

      // project allocation logic
      if (!_projectService.Allocate(Project, Role, int percentage))
      {
          // throw exception
      }

      // allocate to employee
      if(!_employeeService.Allocate(employee, role, percentage))
      {
          // throw exception
      }

      // create new allocation
      _allocationRepository.Add(new Allocation
            {
                ......
            });
}

可以通过构造函数注入分配存储库和服务,例如

The allocation repository and the services can be injected in via the constructor, e.g.

public interface IAllocationRepository
{
       IEnumerable<Allocation> GetAllocationsByProject(Project project);

       IEnumerable<Allocation> GetAllocationsByEmployee(Employee employee);

       void Add(Allocation);
}

IAllocationRepository也可以注入到EmployeeService和ProjectService中,所以你不需要通过分配列表。

The IAllocationRepository can be injected into EmployeeService and ProjectService as well so you don't need to pass the List of Allocation around.

这篇关于业务规则分为两类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆