2014-11-18 3 views
0

Я строю библиотеку обработки, которая будет обрабатывать данные измерений из сенсора. В зависимости от приложения датчика данные могут обрабатываться по-разному. Результат обработки может содержать 1, 2 или 3 выходных значения в зависимости от типа обработки.Как обрабатывать типы ввода и типы вывода с интерфейсами в API?

Я создал несколько enum и interface. Они являются основными типами:

public enum ProcessingType 
{ 
    Default = 0, 
    Type1 = 1, 
    Type2 = 2 
} 

public interface IProcessItem 
{ 
    ProcessingType GetProcessingType(); 
} 

public interface IProcessInputs 
{ 
    string GetID(); 
    float GetTemperature(); 
    IEnumerable<byte> GetProcessData(); 
} 

я в основном проектировании API, которые должны быть документированы и реализованы другим приложением. Моя библиотека процессов будет иметь одну очередь с потоковой обработкой (like here), управляемую одноточечным (like the Multithreaded Singleton example here).

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

Одноэлементный и очередь будет принимать IProcessItem «s:

//Singleton 
public sealed class SignalProcessor 
{ 
    //... 
    public static SignalProcessor Processor 
    { 
     get 
     { 
      //... 
      lock (syncRoot) 
      { 
       processor = new SignalProcessor(); 
      } 
      return processor; 
     } 
    } 

    public void Process(IProcessItem item) 
    { 
     processQueue.Enqueue(item); 
    } 
} 

//Queue 
internal sealed class ProcessQueue : IDisposable 
{ 
    //... 
    public void Enqueue(IProcessItem item) 
    { 
     //add to async queue 
    } 
} 

//Usage 
var po = new ProcessObject(); 
SignalProcessor.Processor.Process(po); 
//...complete and kill thread 

Конкретный объект, который передается из приложения должны иметь все, что необходимо предоставить запрашиваемые данные в процессор данных измерения, а затем сохранить результаты возвращаются в какое-то постоянное хранилище.

Создание интерфейса для ввода легко, потому что они все одинаковы. Однако я не могу понять, как обрабатывать выходные данные. Я начал создавать интерфейсы для типов вывода:

public interface IProcessOutput1 
{ 
    float Level1 { get; set; } 
    SaveData(); 
} 
public interface IProcessOutput2 
{ 
    float Level1 { get; set; } 
    float Level2 { get; set; } 
    SaveData(); 
} 
//etc 

Но если моя обработка двигателя принимает объект, который реализует IProcessInputs, как сохранить выходные значения обратно в объект?

То, что я не могу понять, я должен сделать их должны реализовывать несколько интерфейсов на этом объект, как:

internal class ProcessObject1 : IProcessItem, IProcessInputs, IProcessOutput1 
{ 
    //interface implementations 
} 

internal class ProcessObject2 : IProcessItem, IProcessInputs, IProcessOutput2 
{ 
    //interface implementations 
} 

Или, если я должен объединить интерфейсы в один для каждого типа обработки:

public interface IProcessType2 : IProcessItem 
{ 
    int GetID(); 
    float GetTemp(); 
    float Level1 { get; set; } 
    float Level2 { get; set; } 
    SaveData(); 
} 
//etc. 

ответ

0

Я закончил использовать метод 1 интерфейса типа процесса для каждого типа обработки. Для обработки типа перечисления

public enum ProcessingType 
{ 
    Default = 0, 
    Type1 = 1, 
    Type2 = 2 
} 

Я создал интерфейс для каждого из них:

public interface IProcessingTypeDefault { 
    //... 
} 

public interface IProcessingTypeType1 { 
    //... 
} 

public interface IProcessingTypeType2 { 
    //... 
} 

Поскольку каждый вид обработки имел схожие и различные входы/выходы я думал, мог бы оптимизировать интерфейсы. Но я понял, что попытка оптимизировать количество и содержание каждого интерфейса будет слишком сложной, особенно в свете возможных изменений по пути, который может отрицательно повлиять на оптимизацию.

1

Не уверен, что я следую 100%, но звучит как фабричный шаблон, который принимает перечисление ProcessingType, поскольку параметр может удовлетворить ваши потребности. Что-то вроде ...

public interface IProcessorFactory 
{ 
    IProcessor Create(ProcessingType type); 
} 

internal class ProcessorFactory : IProcessorFactory 
{ 
    IProcessor Create(ProcessingType type) 
    { 
    IProcessor processor = null; 
    // switch statement or perhaps indivual factory implementations for each processor type. 
    // pick your poison 
    switch(type) 
    { 
     case ProcessingType.Default: 
     processor = new DefaultProcessor(); 
     break; 
     ... etc. 
    } 

    return processor; 
    } 
} 

public interface IProcessor 
{ 
    int GetID(); 
    float Value { get; set; } 
    void SaveData(); 
} 

internal class DefaultProcessor : IProcessor 
{ 
    float Value { get; set; } 

    int GetID() 
    { 
    ... 
    } 

    void SaveData() 
    { 
    ... 
    } 
} 
+0

Прошу прощения за то, что я не понимаю в своем вопросе. Это тоже довольно нечеткая идея в моей голове ... Я не совсем уверен, как реализовать то, что мне нужно. Я просмотрю ваш ответ и посмотрю, поможет ли это. Благодаря! – jwatts1980

+0

Уверен, и в случае, если он не станет на 100% понятным. Клиент будет использовать IProcessorFactory для создания экземпляра соответствующего IProcessor. –

+0

+1 за хорошую идею. Сегодня я провел время, изучая образец фабрики. Кажется, что конкретный тип (ы) должен быть создан в серверном приложении, потому что для извлечения данных необходимо выполнить специальную реализацию, а затем сохранить выходы. Шаблон фабрики можно использовать в приложении сервера для создания правильного типа, но я не думаю, что это поможет мне в библиотеке процессов. – jwatts1980

Смежные вопросы