Определите метод интерфейса, который берет различные параметры

Мое приложение использует измерительные инструменты, которые подключены к ПК. Я хочу позволить использовать подобные инструменты от различных поставщиков.

Таким образом, я определил интерфейс:

interface IMeasurementInterface
    {
        void Initialize();
        void Close();
    }

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

interface IMeasurementInterface
{
    void Initialize();
    void Close();
    void Setup(object Parameters);
}

Я тогда брошу объект к тому, в чем я нуждаюсь. Действительно ли это - способ пойти?

11
задан Enrico 26 October 2008 в 16:15
поделиться

6 ответов

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

public interface IMeasurement<PARAMTYPE> where PARAMTYPE : Parameters
{
    void Init();
    void Close();
    void Setup(PARAMTYPE p);
}

public abstract class Parameters
{

}

И затем для каждого определенного Устройства,

public class DeviceOne : IMeasurement<ParametersForDeviceOne>
{
    public void Init() { }
    public void Close() { }
    public void Setup(ParametersForDeviceOne p) { }
}

public class ParametersForDeviceOne : Parameters
{

}
13
ответ дан 3 December 2019 в 06:48
поделиться

Мне это кажется, что Шаблон "фабрика" мог бы быть полезным, особенно если Ваш идут в модульный тест Ваше приложение.

2
ответ дан 3 December 2019 в 06:48
поделиться

Это зависит от того, как Вы собираетесь получить параметры во-первых. Если они будут сохранены прочь в таблице базы данных или файле конфигурации где-нибудь, и это - просто значения, которые должны быть установлены, затем передав в словаре, то вероятно, сделает это (хотя Вы действительно теряете безопасность типов). Если бы Ваши процессы установки будут немного более сложными затем, я считал бы абстракцию далеко процессом установки немного далее и выполнением двойной отправки (продвигающий операцию броска в новый класс установки). Как это

public interface IMeasurementInterface
{
  void Initialize();
  void Close();
  void Setup( IConfigurer config );
}

public interface IConfigurer
{
  void ApplyTo( object obj );
}

public abstract ConfigurerBase<T> : IConfigurer where T : IMeasurementInterface
{
  protected abstract void ApplyTo( T item );

  void IConfigurator.ApplyTo(object obj )
  {
    var item = obj as T;
    if( item == null )
      throw new InvalidOperationException("Configurer can't be applied to this type");
    ApplyTo(item);
  }
}

Таким образом, Вы не портите свою Измерительную иерархию классов (или не обеспечиваете реализации и предполагаете, что все реализации сделают то, что Вы хотите так или иначе). Это также означает, что можно протестировать код Установки путем передачи в фальшивке (или Дразнивший) Устройства измерения.

Если процесс установки должен управлять частными или защищенными данными затем, можно заставить конкретную реализацию IConfigurer находиться в его соответствующем Измерительном классе.

1
ответ дан 3 December 2019 в 06:48
поделиться

Это, вероятно, работало бы. Другая опция состоит в том, чтобы передать параметры в словаре.

0
ответ дан 3 December 2019 в 06:48
поделиться

Если Вы собираетесь иметь дело даже больше чем с одним типом устройства, то контроллер + разделение интерфейса устройства, которое передает Имя использования vlaue пары, был бы хорошим решением

ОТДЕЛЕНИЕ

Используя пары значение-имя позволяет Вам разделять свой код в устройство + контроллер + структура кода приложения

Пример кода

class DeviceInterface
    {
    void Initialize(IController & Controller);
    void Close();
    bool ChangeParameter(const string & Name, const string & Value); 
    bool GetParam(string & Name, string &Value );
    }

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

interface IController
   {
   Initialize(DeviceSpecific & Params);
   Close();
   bool ChangeParameter(string & Name, string & Value);
   bool ChangeParams(string & Name[], string &Value []);
   }

Ваш пользовательский код выглядел бы примерно так

IController     objController = new MeasurementDevice(MeasureParram);

DeviceInterface MeasureDevice = new DeviceInterface(objController);

string Value;

MeasureDevice.GetParam("Temperature", Value);

if (ConvertStringToInt(Value) > 80)
     {
     MeasureDevice.ChangeParameter("Shutdown", "True");
     RaiseAlert();
     }

Все, что должен сделать класс DeviceInterface, заботятся о передаче команд к контроллеру. Контроллер должен заботиться о коммуникации устройства.

Преимущества интерфейсного разделения

Защитите от изменений

Этот вид отделения позволит Вам изолировать свой код приложения от контроллера. Изменения в устройстве не влияют на Ваш пользовательский код

Пригодность для обслуживания кода Appliction

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

Простота реализации

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

Реальная жизнь

Один из последних производственных проектов контроллера от лидера в том домене работает таким же образом. Но они используют LON для коммуникации устройства.

LON?

Протокол LON, используемый в контроллерах (думают кондиционер / бойлер / вентиляторы и т.д.) сети, использует это понятие, чтобы говорить с различными устройствами

Таким образом, все, что Вы должны были бы иметь, является единственным интерфейсом, который может говорить с Вашим устройством и затем отправляет пару значение-имя в него с помощью LON., который он использует стандартного протокола, также позволит Вам говорить с другими устройствами помимо своего измерительного инструмента. Существуют реализации с открытым исходным кодом LON, доступного, если Ваше устройство использует LON.

Если Ваше устройство не поддерживает LON затем, Вам, возможно, придется разработать что-то, где пользовательский код все еще работает над парами значение-имя, и противоположный интерфейс переводит Ваши пары значение-имя в equivalet соответствующую cotroller структуру + и связывается с устройством индивидуумов в способе, которым понимает устройство.

Надежда это прибывает полезное.

1
ответ дан 3 December 2019 в 06:48
поделиться

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

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

Путем я делаю это следующие

interface IMeasurementInterface
{
    void Initialize();
    void Close();
    void Setup();
    void Read (FileReader as <whatever read file object you are using>)
    void Store (FileReader as <whatever read file object you are using>)
    string Name();
}

Установка называет диалоговое окно созданным в блоке IMeasurementDevice. Диалоговое окно не Видимо за пределами блока.

Теперь я знаю, что некоторый объектно-ориентированный или пурист MVC может возразить против этого. Однако я чувствую, что понятие сокрытия внутренностей определенного Измерительного класса перевешивает строгое соблюдение архитектуры MVC.

Моя общая философия - то, что trival диалоговое окно реализовано в том же блоке при условии, что это является частным к блоку и названное реализацией объекта в стандартных интерфейсах, которые я устанавливаю. Снова причина этого, я нахожу, что сокрытие внутренностей более ценно, чем попытка реализовать все диалоговые окна в высокоуровневом блоке.

Путем определения Метода Чтения и метода Хранилища Вы избавляете от необходимости выставлять внутренние параметры установки для сохранения. Все, в чем Вы нуждаетесь, должно передать любой тип объекта хранилища файлов, который что Вы используете для сохранения параметров установки.

Наконец как другой плакат указал, что необходимо установить Класс Фабрики в блоке, содержащем все устройства измерения. Во время Вашей установки необходимо инстанцировать этого класса и получить список поддерживаемых устройств измерения.

Путем я делаю это - мой класс фабрики, получает список контроллеров перемещений. Этот список является частью мастер-класса, где все классы установки хранятся. Когда я считал свои файлы настройки, я получаю контроллеры, которые на самом деле используются. Я получаю те классы из списка и размещаю их в другой список, который на самом деле используется во время сокращающего процесса.

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

1
ответ дан 3 December 2019 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: