我正在开发一个应用程序,它可以在用户需要对各种设备执行预防性维护时提示用户。每件设备(称之为工具)都有不同的重复模式。有些将基于时间,例如每90天,而其他基于其他因素,如使用。例如,特定工具在签出X次后可能需要PM。
所有工具都分配给个人,因此当该用户登录应用程序时,我需要显示当时需要PM的工具列表。当PM完成后,这些项目从列表中删除,并且在其他情况下,例如日期更改或工具被重新检入婴儿床,将添加工具。
我开始设计将返回此列表的服务方法,并且正在寻找一些帮助来解决我用来解决列表中的项目的方法。对于输入,我将拥有用户的标识符和当前日期。由此我需要查询工具列表并根据它们的重复模式确定PM的最后一次执行时间以及自上次PM以来发生的事件,该项目是否应出现在列表中。
希望这是有道理的。我很欣赏有关如何处理这种逻辑的任何想法和指导。
答案 0 :(得分:2)
为了结束,我想我会用我的努力结果来更新帖子,虽然我对Brandon和Florian的答案给予了肯定,因为我发送了正确的道路。
我最终得到了一个接口,正如Brandon建议的那样,调用IHaveRecurrence定义如下:
public interface IHaveRecurrence
{
DateTime? LastOccurrence { get; }
RecurrenceType RecurrenceType { get; }
Int32 RecurrenceValue { get; }
Boolean IsDue();
}
My MaintainableTool(base)类现在实现了这个接口。 IsDue方法是通过委托Recurrence类实现的:
public Boolean IsDue()
{
return Recurrence.IsDue(this);
}
Recurrence是Florian建议的抽象基类。我有几个子类,例如DailyRecurrence,WeeklyRecurrence等。每个子类对应于RecurrenceType枚举中的一个值,并通过IHaveRecurrence接口实现相应的逻辑,以根据RecurrenceValue和LastOccurrence属性确定PM是否到期。 / p>
Recurrence使用内部RecurrenceFactory类来解析要使用的子类:
internal sealed class RecurrenceFactory
{
public Recurrence GetRecurrence(RecurrenceType type)
{
switch (type)
{
case Daily: return new DailyRecurrence;
:
}
}
}
并且重复实施为:
public abstract class Recurrence : IDisposable
{
public static Boolean IsDue(IHaveRecurrence recurringObj)
{
using (var recurrence = RecurrenceFactory.GetRecurrence(recurringObj.RecurrenceType))
{
return recurrence.GetIsDue(recurringObj);
}
}
protected abstract Boolean GetIsDue(IHaveRecurrence recurringObj);
}
然后,例如,DailyRecurrence类实现为:
public sealed class DailyRecurrence : Recurrence
{
protected override Boolean GetIsDue(IHaveRecurrence recurringObj)
{
if (recurringObj.LastOccurred.HasValue)
return recurringObj.LastOccurred.AddDays(recurringObj.RecurrenceValue) <= DateTime.Now;
return true;
}
}
我喜欢这个模型,因为它具有高度可扩展性,它封装了解析每个重复发生模式所需的逻辑,并保持业务对象的清洁。
答案 1 :(得分:1)
听起来我觉得每个工具都有自己的逻辑来判断PM是否需要。所以我会用一些enum定义一个IEquipment接口,如下所示:
public enum RecurrenceType
{
//Values
}
public enum RecurrenceFrequency
{
//Values
}
public interface IEquipment
{
bool IsPMRequired();
RecurrenceType RecurrenceType { get; }
RecurrenceFrequency RecurrenceFrequency { get; }
//You may want to choose something other than object, or eliminate this property
object RecurrenceValue { get; set; }
}
然后每种类型的设备都会实现接口,并且可以实现确定是否需要PM的逻辑:
public class Tractor : IEquipment
{
public bool IsPMRequired()
{
//Implement logic here specific to a Tractor
throw new NotImplementedException();
}
public RecurrenceType RecurrenceType
{
get { throw new NotImplementedException(); }
}
public RecurrenceFrequency RecurrenceFrequency
{
get { throw new NotImplementedException(); }
}
public object RecurrenceValue
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
然后你使用这些对象的逻辑就像:
List<IEquipment> equipment = new List<IEquipment>();
//Populate equipment
List<IEquipment> display = equipment.Where(e => e.IsPMRequired()).ToList();
//Display the equipment that needs PM
在您设置常用方法/属性定义的设备中有一个基类也是有意义的。
答案 2 :(得分:1)
我将定义一个类似于此的抽象类Recurrence:
abstract class Recurrence
{
public abstract bool IsDue(DateTime dateAndTime);
}
现在让Recurrence成为装备的属性。
abstract class Equipment
{
protected abstract Recurrence PMRecurrence
{
get;
}
public bool IsPMDue(DateTime dateAndTime)
{
return PMRecurrence.IsDue(dateAndTime);
}
}
然后,您可以定义Recurs的相应子类,如TimeRecurrence,UsageRecurrence,并将它们的实例分配给设备的适当子类,如Hammer,Tractor,并根据需要实现它们。这应该提供灵活性和可维护性的良好平衡。
祝你好运,看起来像是一项具有挑战性的任务!