Реализация рецидива без даты - PullRequest
0 голосов
/ 01 апреля 2011

Я разрабатываю приложение, которое по сути подсказывает пользователям, когда им необходимо выполнить профилактическое обслуживание на различных элементах оборудования. Каждый элемент оборудования (назовите его инструментом) имеет свою схему повторения. Некоторые будут основаны на времени, например каждые 90 дней, в то время как другие основаны на других факторах, таких как использование. Например, конкретному инструменту может потребоваться PM после того, как он был проверен X раз.

Все инструменты назначены для отдельного человека, поэтому, когда этот пользователь входит в приложение, мне нужно отобразить список инструментов, для которых требуется PM в то время. По завершении PM эти элементы выпадают из списка, и в связи с другими обстоятельствами, такими как изменение даты или возвращение инструмента обратно в кроватку, инструменты будут добавлены.

Я начинаю с разработки метода обслуживания, который будет возвращать этот список, и ищу некоторую помощь с подходом, который я использую для определения того, какие элементы в списке. Для ввода у меня будет идентификатор пользователя и текущая дата. Исходя из этого, мне нужно запросить список инструментов и определить на основе их шаблона повторения, время последнего выполнения PM и события, которые произошли с момента последнего PM, должен ли этот элемент появляться в списке.

Надеюсь, это имеет смысл. Я ценю любые мысли и советы о том, как мне следует подойти к этой логике.

Ответы [ 3 ]

2 голосов
/ 11 апреля 2011

Ради закрытия я подумал, что обновлю пост с результатами моих усилий, хотя я отдаю должное ответу и Брэндона, и Флориана за то, что он отправил меня по правильному пути.

Я закончил с интерфейсом, как предложил Брэндон, под названием IHaveRecurrence, определенным следующим образом:

public interface IHaveRecurrence
{
    DateTime? LastOccurrence { get; }
    RecurrenceType RecurrenceType { get; }
    Int32 RecurrenceValue { get; }
    Boolean IsDue();
}

Мой класс MaintainableTool (base) теперь реализует этот интерфейс.Метод IsDue реализуется путем делегирования классу Recurrence:

public Boolean IsDue()
{
    return Recurrence.IsDue(this);
}

Recurrence - это абстрактный базовый класс, предложенный Флорианом.У меня есть несколько подклассов, таких как DailyRecurrence, WeeklyRecurrence и т. Д. Каждый из подклассов соответствует одному из значений в перечислении RecurrenceType и реализует соответствующую логику, чтобы определить, должен ли PM быть задан на основе свойств RecurrenceValue и LastOccurrence через интерфейс IHaveRecurrence.

Recurrence использует внутренний класс RecurrenceFactory для определения, какой подкласс использовать:

internal sealed class RecurrenceFactory
{
    public Recurrence GetRecurrence(RecurrenceType type)
    {
        switch (type)
        {
            case Daily: return new DailyRecurrence;
            :
        }
    }
}

И Recurrence реализуется следующим образом:

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 голос
/ 01 апреля 2011

Я бы определил абстрактный класс Recurrence, который выглядит следующим образом:

abstract class Recurrence
{
      public abstract bool IsDue(DateTime dateAndTime);
}

Теперь сделайте Recurrence свойством Equipment.

abstract class Equipment
{
      protected abstract Recurrence PMRecurrence
      {
            get;
      }

      public bool IsPMDue(DateTime dateAndTime)
      {
             return PMRecurrence.IsDue(dateAndTime);
      }
 }

Затем вы можете определить соответствующие подклассы Recurrence, например:TimeRecurrence, UsageRecurrence и присваивайте их экземпляры соответствующим подклассам оборудования, таким как Hammer, Tractor, и реализуйте их по мере необходимости.Это должно обеспечить хороший баланс гибкости и удобства обслуживания.

Удачи, кажется сложной задачей!

1 голос
/ 01 апреля 2011

Мне кажется, что у каждого Инструмента будет своя собственная логика для определения, требуется ли PM или нет. Поэтому я бы определил интерфейс 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

Может также иметь смысл иметь базовый класс для Equipment, в который вы помещаете общие определения методов / свойств.

...