【问题标题】:Employee Limitations员工限制
【发布时间】:2009-08-28 01:07:04
【问题描述】:

我正在编写一个 C# 程序来处理调度。现在每个员工都需要有能力限制他们的前任:

Sally 只能在周一、周三、周五上午 9 点至下午 3 点工作

Billy 只能在周二、周四、周日下午 5 点到 9 点工作

Sally 只能在周一、周三、周五上午 9 点至下午 3 点工作 直到某某约会,然后她可以在不同的时间和日期工作。

这些是我需要应用于每个员工对象的一些限制示例。我想要的是一些关于如何尽可能高效和通用地构建它的建议。显然,我必须能够访问这些数据并能够应用这些限制。例如,当经理试图制定时间表时,他需要能够看到,当他在星期二 4 点安排 Sally 时,他们是一个问题。另外我应该如何存储每个员工的这些数据?

【问题讨论】:

    标签: c# architecture scheduling


    【解决方案1】:

    类似这样的:

    public class Employee
    {
        public string Name { get; set; }
        // other important info
    
        private List<WorkTime> _availability = new List<WorkTime>();
        public List<WorkTime> Availability
        {
            get { return _availability; }
            internal set { _availability = value; }
        }
    }
    
    public class WorkTime
    {
        public DayOfWeek Day { get; private set; }
        public int StartHour { get; private set; }
        public int EndHour { get; private set; }
    
        public WorkTime(DayOfWeek day, int startHour, int endHour)
        {
            // validation here (e.g. day and time range during store hours, start<end, etc.)
    
            Day = day;
            StartHour = startHour;
            EndHour = endHour;
        }
    }
    

    并使用 LINQ(或 foreach)在员工集合中进行查询,并查询每个员工的可用性,以找到有时间来满足某些轮班的人。

    根据您的业务规则创建一些用于比较 WorkTime 对象的实用程序函数(扩展)也可能很有用(例如,IsAvailable 比较两个 WorkTime 对象,如果它是相同的 DoW 并且至少有 4 小时重叠,则返回 true)

    您可能会将其存储在数据库中,因此请使用类中的属性等字段对表进行建模。

    【讨论】:

      【解决方案2】:

      我会选择Rules,使用strategy pattern

      public interface Rule
      {
          bool Satisfies(Employee employee);
      }
      
      public class ScheduleRule : Rule
      {
          ScheduleRule(Schedule schedule)
          { ... }
      
          bool Satisfies(Employee employee)
          {
              // Ensure the employee is available
          }
      }
      
      public class HolidayRule : Rule
      {
          HolidayRule(Datetime date)
          { ... }
      
          bool Satisfies(Employee employee)
          {
              // Checks if the employee as volunteered for this holiday
          }
      }
      

      这种模式可以实现轻松的可扩展性和可维护性。

      可用性信息(和其他与规则相关的信息)可以与员工一起保存(请参阅 Mike Jacob 的回答)。但是,它可以与员工一起存储或存储在单独的表中。

      如果您期望大量与规则相关的信息,您也可以将此可用性信息与员工分开。在这种情况下,Rules 可以针对另一个类:

      ...
      bool Satisfies(RuleInfo info)
      ...
      

      【讨论】:

        【解决方案3】:

        我建议提供将“休假”存储为具有时间范围的特定日期或模式的功能。我曾在几个调度系统上工作过,它们处理工会规则和员工可用性的方式非常复杂,这就是我们处理它的方式。

        任何一位员工都说我想要从 y 到 z 的第 X 天,这很容易检查,或者他们可以定义他们想要或不想要的模式(例如,我不想在星期五工作),然后在安排时间时你可以检查将它们应用于特定班次是否违反了既定规则(休息日)或是否匹配特定模式。

        另外我应该如何存储每个员工的这些数据?

        有一个用于存储员工特定异常的表。我想要从 y 到 z 的第 X 天。您有一个员工的日期和时间跨度。很简单。

        至于模式,您需要提出某种类型的模式。并且有类型什么的。

        所以你可以有一个像“每周休假模式”这样的类型,它将存储一周的全天休假,可以存储为表示休假天数的简单字符串:1000001。假设第一位是星期天,这将表示想要周末休息。然后,您可以将模式存储为字符串或其他内容,然后根据定义的类型,您将知道如何处理字符串。

        这可能是一个非常复杂或简单的问题,这取决于您需要允许多少自定义。希望这可以为您提供足够的想法来帮助您入门。

        根据您需要支持的例外/规则,自动生成计划要复杂得多。

        【讨论】:

        • 基本上是一个很好的设计 - 但是 - 我会颠倒这个,以便“时间”是你存储的。这毕竟是你真正感兴趣的。位图看起来很吸引人,但最终可能会成为一个真正的痛苦。我可能会将它作为 emp、available_from、avalable_to 存储在数据库中。这将使经理能够查询“谁在星期六下午”。位图也只能给你一个在这里或不在这里的数据。存储在数据库中为你提供了更丰富的选项,例如预定的、可用的、仅在紧急情况下可用。
        • 我的例子是任何模式。你可以存储任何东西。考虑到工作时间比休息时间更常见,我还没有看到任何调度系统存储可用性数据。关键是在不处理绝对数据时使用模式。
        【解决方案4】:

        “尽可能高效和通用地构建它”

        这些本身并不是相互排斥的,但是高效和通用真的很难实现,尤其是在调度系统。调度是一个非常重要的问题。

        您的问题可能会更好地表述为“我应该阅读哪些书才能开始学习?”和/或将其设为社区 wiki。

        【讨论】:

          【解决方案5】:

          这类似于graph-matching 问题,也可以建模为Constraint Satisfaction Problem。您可能会发现 NSolver 很有帮助,或者 Cassowary.Net

          【讨论】:

            【解决方案6】:

            我做过类似的事情,我所做的是创建一个通用接口,然后为不同的场景创建单独的实现。该接口可能有一个检查 IsInSchedule(dateTime)。然后您可以根据需要创建不同的实现。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-09-15
              • 1970-01-01
              • 1970-01-01
              • 2013-09-07
              相关资源
              最近更新 更多