tutorial interfaz gui grafica español java design-patterns visitor-pattern

java - gui - Solución Patrón de visitante: pocos visitantes tienen la misma interfaz, pero deberían trabajar con diferentes objetos



java swing tutorial pdf español (3)

Podrías hacer esto por ejemplo:

public interface IVisitor<T extends INetworkCard> { public void visit( T card ); }

Y luego definirías a tus visitantes como:

public class WiredVisitor implements IVisitor<WiredNetworkCard> { ... } public class WirelessVisitor implements IVisitor<WirelessNetworkCard> { ... }

Puede que esta no sea la solución de libros de texto, pero es muy limpia y muy legible.

Tengo el siguiente diagrama de clase (implementación de patrón de visitante):

Resultado Esperado:
1) WiredVisitor debe visitar solo Router y WiredNetworkCard
2) WirelessVisitor debe visitar solo Router y WirelessNetworkCard

Entonces, mi pregunta es: ¿cómo debo cambiar el diseño (o el código) para lograr mi resultado esperado?

PD: Mi solución actual es agregar el siguiente fragmento de código a cada visita (tarjeta: tarjeta de red) en ambos visitantes:

// in WiredVisitor if (card.getClass.equals(WiredNetworkCard.class)){ // do logic of visit method } // in WirelessVisitor if (card.getClass.equals(WirelessNetworkCard.class)){ // do logic of visit method }


Creo que el problema aquí no es con el visitante, sino que cuando el cliente llama acepta en WiredNetworkCard pasando un WirelessVisitor que es un error. Debería manejarse entonces levantando una excepción en ese punto en el tiempo.

Pero todo esto sucede en tiempo de ejecución y la solución de biziclop lo maneja en tiempo de compilación. Pero lo que no me gusta de la solución de biziclop es que WiredVisitor que implementa IVisitor<WiredNetworkCard> también tendrá un método de visit(router:Router) que no está relacionado de ninguna manera con WiredNetworkCard


En el espíritu del patrón de visitante acíclico , separa a tus visitantes en subclases específicos. Tenga en cuenta que aún necesitará la verificación de tipo, pero está incluida en el tipo que se está visitando:

Aquí están las interfaces de visitante:

interface IVisitor { } interface IRouterVisitor extends IVisitor { void visit(Router router); } interface INetworkCardVisitor extends IVisitor { } interface IWirelessNetworkCardVisitor extends INetworkCardVisitor { void visit(WirelessNetworkCard card); } interface IWiredNetworkCardVisitor extends INetworkCardVisitor { void visit(WiredNetworkCard card); }

Los visitantes concretos se verán así:

class WiredVisitor implements IWiredNetworkCardVisitor, IRouterVisitor { // ... } class WirelessVisitor implements IWirelessNetworkCardVisitor, IRouterVisitor { // ... }

Y los objetos visitados:

interface INetworkElement { void accept(IVisitor visitor); } class Router implements INetworkElement { @Override public void accept(IVisitor visitor) { if (visitor instanceof IRouterVisitor) { ((IRouterVisitor)visitor).visit(this); } } } interface INetworkCard extends INetworkElement {} class WiredNetworkCard implements INetworkCard { @Override public void accept(IVisitor visitor) { if (visitor instanceof IWiredNetworkCardVisitor) { ((IWiredNetworkCardVisitor)visitor).visit(this); } } } class WirelessNetworkCard implements INetworkCard { @Override public void accept(IVisitor visitor) { if (visitor instanceof IWirelessNetworkCardVisitor) { ((IWirelessNetworkCardVisitor)visitor).visit(this); } } }

En esas comprobaciones de tipo, también puede lanzar un error si el tipo no es el esperado, dependiendo de lo que le gustaría que ocurra en ese caso.