2011-10-21 18 views
6

Tengo una clase realmente horrible con dos métodos que inician o detienen algunos servicios cuando esos servicios están disponibles. Algo así como lo siguiente (si no son-vigilara, solo si):Un patrón de diseño para evitar múltiples ifs

void startServices() { 
if (service1 == true) { 
    start1(); 
} 
if (service2 == true) { 
    start2(); 
} if (serviceN == true) { 
    startN(); 
} 
} 


void stopServices() { 
if (service1 == true) { 
    stop1(); 
} 
if (service2 == true) { 
    stop2(); 
} 
if (serviceN == true) { 
    stopN(); 
} 

} 

¿Me recomiendan que cualquier golpeteo diseño para hacerlo más bonito?

Gracias!

+0

No responderé esto porque las respuestas existentes son buenas, pero me gustaría señalar que '== true' es algo redundante en cualquier' if() '. –

Respuesta

4

Depende; mi primera reacción es almacenar los servicios en un hash o matriz. Cada servicio implementa una interfaz con métodos de inicio y detención. Iniciar o detener un servicio requiere solo una clave o índice de servicio.

Todavía es un poco frágil, quizás, pero sin saber más no estoy seguro de cómo "dominar" ut para que se parezca más a lo que estás haciendo.

4

Puede usar el patrón de Estrategia.

La idea es que usted debe saber qué estrategia va a utilizar cuando cree una instancia de su clase (o puede cambiarla de forma dinámica por latrr). Por lo tanto, puede pasar esa estrategia al instanciar (y opcionalmente reemplazarla más adelante).

public interface IStartupStrategy 
{ 
    void Start(); 
} 

public interface IStopStrategy 
{ 
    void Stop(); 
} 

public class MyClass 
{ 
    private readonly IEnumerable<IStartupStrategy> startupStrategies; 
    private readonly IEnumerable<IStopStrategy> stopStrategies; 

    public MyClass(IEnumerable<IStartupStrategy> startup, IEnumerable<IStopStrategy> stop) 
    { 
     this.startupStrategies = startup; 
     this.stopStrategies = stop; 
    } 

    public void Start() 
    { 
     foreach(var strategy in this.startupStrategies) 
     { 
      strategy.Start(); 
     } 
    } 

    public void Stop() 
    { 
     foreach(var strategy in this.stopStrategies) 
     { 
      strategy.Stop(); 
     } 
    } 
} 
+0

Esto me da la impresión de que el patrón de Estrategia se aplicó ciegamente a este problema. No creo que el nombramiento tenga demasiado sentido; hay múltiples estrategias de puesta en marcha? Uno para cada servicio? – Guven

+1

De hecho. Estaba tratando de dar una representación clara del patrón, pero al hacerlo rompí lo que * debería * haber sido un "servicio IS" en múltiples estrategias de inicio y finalización. Lo ideal sería utilizar la interfaz "IService" que tendría los métodos de inicio y parada. Entonces ese servicio puede decidir si quiere implementar el inicio o la detención. Los servicios se aprobarán en función de los servicios disponibles, y la clase que realiza la llamada decidirá * cuándo * esos servicios se deben iniciar o detener. Sigue siendo el patrón de estrategia, pero la estrategia tendría más de un método. –

+0

Acabo de volver a leer lo que escribí en el comentario anterior. Si el patrón de estrategia pasa esencialmente en algún algoritmo para ser ejecutado que la clase llamante no suministra ... ¿la inversión del control como un todo posiblemente se podría considerar un patrón de estrategia? Solo un pensamiento. –

2

Use Objects, donde tiene una lista de servicios que puede repetir apagándolos con un método heredado stop().

public interface Service { 
    void start(); 
    void stop(); 
} 

public class TestService implements Service { 
    @Override 
    void start() { 
    } 

    @Override 
    void stop() { 
    } 
} 

Cada servicio también puede almacenar su estado de forma que sólo para apagarlos si están en.

0

Las instrucciones de cambio son menos confusas. Si se usa junto con enums, el código se vuelve muy legible.

Cuestiones relacionadas