Estoy desarrollando una aplicación que se usará para abrir y cerrar válvulas en un entorno industrial, y estaba pensando en algo simple como esto:
public static void ValveController
{
public static void OpenValve(string valveName)
{
// Implementation to open the valve
}
public static void CloseValve(string valveName)
{
// Implementation to close the valve
}
}
(La implementación escribiría unos pocos bytes de datos en el puerto serie para controlar la válvula: una "dirección" derivada del nombre de la válvula y un "1" o "0" para abrir o cerrar la válvula).
Otro desarrollador preguntó si deberíamos crear una clase separada para cada válvula física, de las cuales hay docenas. Estoy de acuerdo en que sería mejor escribir código en PlasmaValve.Open()
lugar de ValveController.OpenValve("plasma")
, pero ¿es excesivo?
Además, me preguntaba cuál sería la mejor manera de abordar el diseño teniendo en cuenta un par de requisitos hipotéticos futuros:
- Se nos pide que admitamos un nuevo tipo de válvula que requiere diferentes valores para abrirla y cerrarla (no 0 y 1).
- Se nos pide que apoyemos una válvula que se puede configurar en cualquier posición de 0 a 100, en lugar de simplemente "abrir" o "cerrar".
Normalmente usaría la herencia para este tipo de cosas, pero recientemente he empezado a entender la "composición sobre la herencia" y me pregunto si hay una solución más ingeniosa con la composición.
fuente
Respuestas:
Si cada instancia del objeto de válvula ejecutara el mismo código que este ValveController, entonces parece que múltiples instancias de una sola clase serían el camino correcto. En este caso, simplemente configure qué válvula controla (y cómo) en el constructor del objeto de la válvula.
Sin embargo, si cada control de válvula necesita un código diferente para ejecutarse, y el ValveController actual está ejecutando una declaración de interruptor gigante que hace cosas diferentes según el tipo de válvula, entonces ha implementado mal el polimorfismo. En ese caso, vuelva a escribirlo en varias clases con una base común (si eso tiene sentido) y deje que el principio de responsabilidad única sea su guía de diseño.
fuente
Mi mayor queja es usar cadenas para el parámetro que identifica la válvula.
Al menos, cree una
Valve
clase que tengagetAddress
la forma que necesita la implementación subyacente y páselos alValveController
y asegúrese de que no puede crear válvulas inexistentes. De esta manera, no tendrá que manejar cadenas incorrectas en cada uno de los métodos de apertura y cierre.Si usted crea métodos convenientes que llaman a abrir y cerrar
ValveController
depende de usted, pero para ser sincero, mantendría toda la comunicación con el puerto serie (incluida la codificación) en una sola clase a la que otras clases llamarán cuando sea necesario. Esto significa que cuando necesita migrar a un nuevo controlador, solo necesita modificar una clase.Si le gusta la prueba, también debe hacer
ValveController
un singleton para poder burlarse de él (o crear una máquina de entrenamiento para los operadores).fuente