Pregunta

Me dan este conjunto de código y necesito sugerir formas de mejorar la cohesión y el acoplamiento de las clases del código. Pero pensé que estas clases están bastante bien desacopladas, ya que parece que están haciendo uso de eventos. Y en términos de cohesión, todas las llamadas init () se colocan juntas, todo me parece bastante bien.

public class A
{
    private C t;
    private B g;
    public static void main(String args[]) {
        // Creates t and g.
        t = new C();
        t.init();
        g = new B();
        g.init();
        g.start(this);
    }
    pubic void update (Event e)
    {
        // Performs updating of t based on event
    }
}

public class C
{
    public C() { ... }
    public void init() { ... }
}

public class B
{
    public B() { ... }

    public void init() { ... }

    public void start(A s) {
        e = getNextEvent();
        while (e. type != Quit)
            if (e.type == updateB)
                update(e) ;
            else
                s.update(e) ;
        e = getNextEvent();
    }

    public void update(Event e) { ... }
    }
}

¿Todavía hay formas de mejorar la cohesión y el acoplamiento de las clases? Me parece bien, pero creo que me estoy perdiendo algo.

Gracias por cualquier sugerencia sobre esto.

¿Fue útil?

Solución

Una sugerencia sería desacoplar el manejo de eventos de la lógica de la lógica del controlador (Clase A).

Entonces tendrías 4 tipos de clases:

  • La clase principal utilizada para ejecutar el "servidor" (a)
  • el hilo escuchando eventos (b)
  • la capa del modelo que se actualizará (c)
  • Una clase de controlador de eventos que admitirá alguna operación en un evento (d)

Podría parecer algo así:

public class Main {
  private Model m;
  private EventListener listener;

  ... main() {
    m = new Model();
    listener = new EventListener();

    EventHandler eventHandler = new MyEventHandler();

    // set the event handler
    listener.setEventHandler(eventHandler);

    listener.start(m);
}

public class Model {
  // nothing to see here
}

public class EventListener() {

  private EventHandler handler = new DefaultEventHandler();

  public void start(final Model m) {
    // startup
    while (event.type != Event.Quit) {
      // get event
      handler.handleEvent(event, m);
    }
    // shutdown
  }

  public void setEventHandler(EventHandler eh) { this.handler = eh }
}

public class MyEventHandler implements EventHandler {

  public void handleEvent(Event e, Model m) {
    // update the model
  }

}

Tenga en cuenta que en este nuevo diseño, la lógica comercial de actualizar el modelo (C en su ejemplo) se ha movido a una clase externa en lugar de la clase "corredor". Esto es un poco más limpio ya que la clase principal no necesita tener conocimiento de qué eventos son y cómo manejarlos.

Otra ventaja es que al usar esto puede codificar fácilmente el manejo de eventos complejos utilizando manejadores de eventos encadenados o múltiples manejadores de eventos en serie. También es bastante simple implementar el manejo de eventos asincrónicos, ya que B solo está a cargo de llamar a los manejadores y no necesita comprender los tipos de eventos. Esto a veces se conoce como Publicar/suscribirse y mantiene al oyente (b) y al controlador (su actualización (e) método)

Otros consejos

Comience a escribir pruebas unitarias (mejor aún, hacer TDD). El acoplamiento (y, en menor medida, la cohesión o la falta de ella) será inmediatamente evidente.

Por ejemplo, el método de inicio de Clase B tiene un parámetro de tipo A. En su ejemplo, podría instanciar A, pero ¿qué pasaría si A tuviera otras dependencias? Quizás todas las necesidades de inicio es una interfaz que implementa (con un método de actualización).

¿Y qué hace GetNextEvent? Si usa otras dependencias, obtener B en un arnés de prueba puede resultar difícil.

Las pruebas pueden ayudar a validar su diseño.

Sin ver más de su código, es difícil decir cuán desacoplado es su código. Los eventos son una forma de decouple el código, pero también pueden hacer que el código sea más difícil de entender y depurar.

Al diseñar clases, la alta cohesión significa que muchos de los métodos se reutilizan entre sí, y el bajo acoplamiento significa que solo necesita exponer algunos métodos públicos.

Al diseñar paquetes, la alta cohesión significa que muchas de las clases en un paquete dependen entre sí, y el bajo acoplamiento significa que solo unos pocos son de alcance público o mensajes con otras clases a través de interfaces.

Los beneficios de la alta salina y el bajo acoplamiento deben ser menos dolor, especialmente cuando se trata de responder al cambio. Si no reduce el dolor, no pase mucho tiempo optimizándolo. Sé que parece que estoy dando tópicos aquí, pero debes tener en cuenta tu propia métrica al medir si la alta salina y el bajo acoplamiento es "lo suficientemente bueno" en lugar de confiar en las opiniones de las personas que no necesariamente entienden el Problema que está tratando de resolver.

Si el diseño original es incorporar otra funcionalidad o clases en el futuro, utilizando un controlador de eventos, como usted dijo, se ha utilizado, solo concentrarse en el patrón de estrategia en la implementación y la optimización en clases o interfaces.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top