如何建模对象以跟踪设备/资产?

时间:2010-08-06 21:00:18

标签: c# oop domain-driven-design domain-model

我一直在试图找出建模这个实体的最佳方法,而且我陷入困境。这是基本用例/故事:

我们有设备到达现场。在它到达之前我们不知道设备是什么。一旦设备到达现场,必须将其记录为已到达以及是否空闲或活动。如果它处于活动状态,则用户必须记录设备执行的工作。当设备离开现场时,必须注意这一点。

我应该能够轻松地查询网站上是否有任何设备,以前现场使用的设备等等。

我在日期方面陷入困境。我试图避免依赖一个cron作业来运行并将设备标记为空闲,如果它在特定日期没有被标记为空闲的话。感觉应该有办法做到这一点。以下是我的想法:

public class Equipment {
    public int Id { get; set; }
    public Site Site { get; set; }
    public DateTime Arrival { get; set; }
    public DateTime Departure { get; set; }
    public IList<EquipmentUtilization> EquipmentUtilizations { get; set; }
}

public class EquipmentUtilization {
    public int Id { get; set; }
    public Equipment Equipment { get; set; }
    public DateTime ReportDate { get; set; }
    public string WorkPerformed { get; set; }
}

我的想法是,我可以运行Site.Equipment.Where(x=>x.Departure == null)之类的查询来查看哪些设备仍在现场。如果特定日期没有EquipmentUtilization,则假设是空闲的。然后我可以设置DateTimeEnumerator:

public class DateTimeEnumerator : System.Collections.IEnumerable
{
    private DateTime begin;
    private DateTime end;

    public DateTimeEnumerator ( DateTime begin , DateTime end ) 
    {            
        this.begin = begin;
        this.end = end;
    }
    public System.Collections.IEnumerator GetEnumerator()
    {
        for(DateTime date = begin; date < end; date = date.AddDays(1))
        {
            yield return date;
        }
    }
}

建立从到达日期到DateTime.Now或DepatureDate的日期列表,如果它不为空。出于某种原因,这似乎很难看。我应该将DateTime枚举器放在Equipment对象中吗?感觉这应该是全部在一起或以某种不同的方式完成,尽管如果我运行它确实有效。建议?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,您可以根据捕获的与您的设备相关联的设备使用对象(可能是EquipmentResidency是一个更好的名称?)集合,找到确定给定日期某个设备闲置设备的方法。

由于您希望避免在空闲时间创建设备使用对象(我同意这可能是重要的维护),如何向deviceutilization类添加isIdleOn(Date)方法,如果传递的Date与捕获的ReportDate匹配,则返回true如果没有?

关联的查询将与Site.Equipment.Where(x =&gt; x.equipmentutilization.isIdleOn(date)== true)

一致。

不确定我的语法是否合适,只是一个建议。

答案 1 :(得分:0)

我看到的一个潜在问题是一台设备只知道它当前的站点。如果您想知道2个月前Loader123是否在SiteXYZ,您无法使用当前模型检索该信息。

看起来您的使用粒度是针对特定日期的。如果在SiteABC上从晚上11点到凌晨4点,然后在SiteXYZ下午1点到5点使用一台设备,那肯定会让事情更简单,因为你不需要弄清楚如何跟踪它。

考虑到这些因素,我会对您的模型进行一些细微的改动。我会保留设备所在的所有站点的集合(Equipment.History),并提供便利功能来查找它当前所在的站点(无论SiteHistory.Departure没有值)。对于利用本身,我会提供一个便利函数来将它们作为字典返回,由DateTime键入。然后,您可以对该词典的密钥集合进行操作,以便轻松计算在给定时间段内实际使用设备的天数。

public class Equipment 
{
    public int Id { get; set; }
    public IList<SiteHistory> History { get; set; }
    public IList<EquipmentUtilization> EquipmentUtilizations { get; set; }
    public IDictionary<DateTime, EquipmentUtilization> UtilizationsDictionary { get{...} }
    public Site CurrentSite { get{...} }
}

public class SiteHistory {
    public Site Site { get; set; }
    public DateTime Arrival { get; set; }
    public DateTime? Departure { get; set; }
}

public class EquipmentUtilization {
    public int Id { get; set; }
    public Equipment Equipment { get; set; }  // is this a circular-reference back to the parent?  Might be able to omit it.
    public DateTime ReportDate { get; set; }
    public string WorkPerformed { get; set; }
}

与任何快速肮脏的设计一样,我确信这个有一些漏洞,可以使用一些改进。但希望它能让你更接近你正在寻找的东西。

答案 2 :(得分:0)

我个人没有DateTime枚举器;就像你说的,这听起来不对。

我必须承认,当你说某些事情应该被归类为无所事事时,我很难跟随你。无论你用什么来确定某些东西是否闲置,你都可以放入一个属性,例如:

public class Equipment
{ 
    public int Id { get; set; } 
    public Site Site { get; set; } 
    public DateTime Arrival { get; set; } 
    public DateTime Departure { get; set; } 
    public IList<EquipmentUtilization> EquipmentUtilizations { get; set; }

    public bool IsIdle
    {
        get
        {
            // This checks if the EquipmentUtilizations is empty
            // or if the Equipment is older than three days
            return (this.EquipmentUtilizations == null) ||
                   ((this.Departure == null) &&
                    (this.Arrival < DateTime.Today.AddDays(-3))
        }
    }
}