2008-10-26 13 views
11

Mi aplicación utiliza instrumentos de medición que están conectados a la PC. Quiero hacer posible el uso de instrumentos similares de diferentes proveedores.Defina un método de interfaz que tome diferentes parámetros

Así que define una interfaz:

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

Hasta aquí todo bien. Antes de una medición necesito configurar el instrumento y esto significa para diferentes instrumentos parámetros muy diferentes. Por eso quiero definir un método que toma parámetros que pueden tener estructuras diferentes:

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

voy a continuación, enviar el objeto a lo que necesito. ¿Es este el camino a seguir?

+0

¿Está planeando probar las diferentes clases de instrumentos concretos o está utilizando simuladores y varificación de hardware? – Kasper

+0

Voy a utilizar pruebas unitarias – Enrico

Respuesta

0

Eso probablemente funcione. Otra opción es pasar los parámetros en un diccionario.

13

Será mejor que veas una clase abstracta de "Parámetros" que se amplía con los parámetros de cada instrumento diferente ... p. Ej. y luego usando los genéricos para asegurar que los parámetros correctos se pasan a las clases correctas ...

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

public abstract class Parameters 
{ 

} 

Y a continuación, para cada dispositivo específico,

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

public class ParametersForDeviceOne : Parameters 
{ 

} 
+0

Los parámetros deben ser una interfaz, ¿no? Prefiero la descripción 'Configuración' en contraposición a la configuración. – Egwor

+0

Gracias por su respuesta, sin embargo, esto plantea otra pregunta. En mi modelo tengo un campo privado llamado: MeasurementDevice que debe ser del tipo IMeasurement Si quiero iniciar DeviceOne lo hago: MeasurementDevice = new DeviceOne() Esto no funciona (no se puede convertir DeviceOne. – Enrico

+1

Al crear un dispositivo Necesitará saber el tipo de dispositivo que es para mantener una referencia a través de la interfaz, por lo que pierde el poder de la abstracción un poco –

2

Para mí sonar como el patrón podría ser Factory útil, especialmente si va a probar su aplicación en una unidad.

1

Si se va a tratar con incluso más de un tipo de dispositivo, a continuación, la separación del regulador + dispositivo de interfaz, que se comunica utilizando pares Nombre vlaue sería una buena solución

DESACOPLE

Utilización del valor de nombre pares le permite separar sus código en un dispositivo controlador + estructura + código de la aplicación

código de ejemplo

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

Cada implementación dispositivo, cuando se crea debe ser creado con la identificación del controlador que puede aceptar sus órdenes y traducirlos en el dispositivo real comandos

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

Su código de usuario se vería algo como esto

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(); 
    } 

Todo lo que debe hacer la clase DeviceInterface es hacer pasar los comandos al controlador. El controlador debe encargarse de la comunicación del dispositivo.

ventajas de la separación de interfaz

Proteger cambia Againt

Este tipo de desacoplamiento le permitirá aislar el código de aplicación desde el controlador.Los cambios en el dispositivo no afecta a su código de usuario

mantenimiento del código Appliction

Addtionally el código de usuario está siempre limpio y hay que molesta sólo con la lógica de la aplicación. Pero si hubiera definido múltiples interfaces/plantillas creadas o genéricos con múltiples tipos de estructuras de parámetros específicas para el controlador, su código tendría mucha basura dependiente del dispositivo que podría dañar la legibilidad y crear problemas de mantenimiento cada vez que cambie su dispositivo/sus parámetros.

facilidad de implementación

También puede desprenderá de diferentes implementaciones de controladores en sus propios proyectos. Además, su aplicación también puede configurar comandos y respuestas de una manera más dinámica utilizando archivos XML, etc. que pueden enviarse junto con las clases de controlador de modo que toda su aplicación se vuelva más dinámica por naturaleza.

Vida Real

Uno de los últimos proyectos de contralor de la producción de la empresa líder en ese dominio funciona de la misma manera. Pero usan LON para la comunicación del dispositivo.

LON?

protocolo LON se utiliza en los controladores (piensa acondicionador de aire/caldera/ventiladores, etc) de las redes utilizan este concepto para hablar con varios dispositivos

Así que todo lo que usted necesita tener es una interfaz única que puede hablar con su dispositivo y luego le envía el par de nombre y valor usando LON. El uso de un protocolo estándar también le permitirá hablar con otros dispositivos además de su instrumento de medición. Existen implementaciones de código abierto de LON disponibles si su dispositivo usa LON.

Si su dispositivo no es compatible con LON, tendrá que diseñar algo donde el código de usuario aún funcione en pares de valores nominales y una interfaz opuesta traduzca sus pares de valores nominales en una estructura cotroller correspondiente equivalente y se comunique al dispositivo individual en la forma en que el dispositivo entiende.

Espero que esto sea útil.

1

Depende de cómo va a obtener los parámetros en primer lugar. Si están almacenados en una tabla de base de datos o un archivo de configuración en algún lugar y solo son valores que deben establecerse, pasarlo en un diccionario probablemente lo haga (aunque se pierde seguridad de tipo). Si sus procesos de configuración van a ser un poco más complicados, consideraría abstraer el proceso de configuración un poco más y realizar un despacho doble (empujando la operación de conversión a una nueva clase de configuración). Al igual que este

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); 
    } 
} 

De esta manera no está arruinando su jerarquía de clases de medida (o proporcionar ninguna implementación y suponiendo que todas las implementaciones van a hacer lo que quiere de todos modos). También significa que puede probar su código de instalación pasando un dispositivo de medición falso (o burlado).

Si el proceso de instalación necesita manipular datos privados o protegidos, puede hacer que la implementación concreta del IConfigurer resida dentro de su clase de medición correspondiente.

1

Tengo que esto para mi software ya que necesito admitir muchos tipos diferentes de controladores de movimiento para máquinas de corte de metales.

Su interfaz tiene lo básico que necesita. Lo que debe recordar es que no necesita pasar una lista de parámetros. Usted señaló que cada tipo de dispositivo podría tener un tipo de configuración muy diferente.

La manera de hacerlo es la siguiente

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(); 
} 

instalación llama un cuadro de diálogo creado en el montaje de la IMeasurementDevice. El cuadro de diálogo NO es visible fuera del ensamblaje.

Ahora sé que algunos objetos orientados o puristas MVC pueden oponerse a esto. Sin embargo, creo que el concepto de ocultar las partes internas de una clase de medición específica supera la adhesión estricta a la arquitectura MVC.

Mi filosofía general es que el diálogo trival se implementa en el mismo ensamblado, siempre que sea privado para el ensamblado y lo invoque un objeto que implemente las interfaces estándar que configuro. Una vez más, la razón de esto es que encuentro que ocultar las partes internas es más valioso que tratar de implementar todos los cuadros de diálogo en el ensamblaje de nivel superior.

Al especificar un Método de lectura y un método de Tienda, elimina la necesidad de exponer los parámetros de configuración internos para guardar. Todo lo que necesita es pasar cualquier tipo de objeto de almacenamiento de archivos que esté utilizando para guardar sus parámetros de configuración.

Por último, al igual que otro afiche indicó que debe configurar una clase de fábrica en su conjunto que contenga todos sus dispositivos de medición. Durante la configuración, debe crear una instancia de esta clase y recuperar la lista de dispositivos de medición admitidos.

La forma en que lo hago es que mi clase de fábrica recupera una lista de controladores de movimiento. Esta lista es parte de una clase maestra donde se almacenan todas las clases de configuración. Cuando leo mis archivos de configuración, obtengo los controladores que realmente están siendo utilizados. Recupero esas clases de la lista y las coloco en otra lista que realmente se usa durante el proceso de corte.

La razón por la que lo hago de esta manera es que cuando el usuario está configurando controladores de movimiento debe poder elegir de una lista de TODOS los controles disponibles para decirle al software cuál tiene. Encuentro más receptivo mantener una lista de controladores disponibles.

+0

Esto podría funcionar, pero necesito pasar algunos parámetros de configuración desde la UI, sin abrir un cuadro de diálogo. Solo quiero cambiar el número de puntos para medir Quiero hacer eso desde la interfaz de usuario principal y no desde una configuración de di un registro.Por lo tanto, quería que la configuración aceptara los parámetros – Enrico

+0

. En nuestro software tenemos estándares de tienda a los que se puede acceder desde cualquier lugar del software. Recomiendo colocar ese parámetro (y otros similares) en su versión de los Estándares de la tienda. –

+0

Qué parámetro va donde uso la regla de 1) Si se refiere a TODOS los dispositivos de la misma clase. Ponga en los estándares de Global Shop. 2) Si es específico del dispositivo, escóndalo detrás de la interfaz del dispositivo. En otro caso, no necesita pasar parámetros adicionales a través de la configuración. –

Cuestiones relacionadas