14. Modo visitante visitante

Encapsula algunas operaciones que actúan sobre cada elemento en una determinada estructura de datos, se pueden definir nuevas operaciones que actúan sobre estos elementos sin cambiar la estructura de datos.

Diagrama de clase

Ejemplo de código

El patrón de visitantes es probablemente el más complicado de los patrones de comportamiento.

1.	class A {  
2.	    public void method1(){  
3.	        System.out.println("我是A");  
4.	    }  
5.	      
6.	    public void method2(B b){  
7.	        b.showA(this);  
8.	    }  
9.	}  
10.	  
11.	class B {  
12.	    public void showA(A a){  
13.	        a.method1();  
14.	    }  
15.	}  

Principalmente miramos la diferencia entre el método1 y el método2 en la clase A. El método1 es muy simple, solo imprime una oración "Soy A"; el método2 es un poco más complicado, usa la clase B como parámetro y llama a la clase Método showA de B. Veamos el método showA de la clase B. El método showA usa la clase A como parámetro, y luego llama al método method1 de la clase A. Puede ver que el método method2 da vueltas, no es más que llamar a su propio método method1, y se ejecuta El resultado también debería ser "Soy A". Después del análisis, ejecutemos estos dos métodos y veamos los resultados:

 

1.	public class Test {  
2.	    public static void main(String[] args){  
3.	        A a = new A();  
4.	        a.method1();  
5.	        a.method2(new B());  
6.	    }  
7.	}  

El resultado de ejecución es:

Yo soy un
yo soy un

Después de leer este ejemplo, puede comprender el 90% del patrón de visitantes. En el ejemplo, para la clase A, la clase B es un visitante. Pero este ejemplo no es todo el patrón de visitantes. Aunque es intuitivo, su escalabilidad es relativamente pobre. Hablemos de la implementación general del patrón de visitantes. Puede ver a través del diagrama de clases que en el patrón de visitantes, el principal Incluyendo los siguientes roles:

  1. Visitante abstracto: Clase o interfaz abstracta, que declara qué elementos puede visitar el visitante. Específicamente, los parámetros en el método de visita definen qué objetos se pueden visitar en el programa.
  2. Visitante: implementa el método declarado por el visitante abstracto, que afecta lo que el visitante debe hacer después de visitar una clase.
  3. Clase de elemento abstracto: interfaz o clase abstracta, que declara a qué tipo de visitante se le permite acceder, que se define programáticamente a través de los parámetros en el método accept. Los elementos abstractos generalmente tienen dos tipos de métodos, uno de los cuales es su propia lógica comercial y el otro es qué tipos de visitantes pueden acceder.
  4. Clase de elemento: implemente el método de aceptación declarado por la clase de elemento abstracto, generalmente visitante.visita (esto), que básicamente ha formado una fórmula fija.
  5. Objeto estructural: un contenedor de un elemento, que generalmente contiene un contenedor de múltiples clases diferentes y diferentes interfaces, como Lista, Conjunto, Mapa, etc. Este rol rara vez se abstrae en los proyectos.

Implementación de código general del patrón de visitante:

1.	abstract class Element {  
2.	    public abstract void accept(IVisitor visitor);  
3.	    public abstract void doSomething();  
4.	}  
5.	  
6.	interface IVisitor {  
7.	    public void visit(ConcreteElement1 el1);  
8.	    public void visit(ConcreteElement2 el2);  
9.	}  
10.	  
11.	class ConcreteElement1 extends Element {  
12.	    public void doSomething(){  
13.	        System.out.println("这是元素1");  
14.	    }  
15.	      
16.	    public void accept(IVisitor visitor) {  
17.	        visitor.visit(this);  
18.	    }  
19.	}
20.	class ConcreteElement2 extends Element {  
21.	    public void doSomething(){  
22.	        System.out.println("这是元素2");  
23.	    }  
24.	      
25.	    public void accept(IVisitor visitor) {  
26.	        visitor.visit(this);  
27.	    }  
28.	}  
29.	class Visitor implements IVisitor {  
30.	  
31.	    public void visit(ConcreteElement1 el1) {  
32.	        el1.doSomething();  
33.	    }  
34.	      
35.	    public void visit(ConcreteElement2 el2) {  
36.	        el2.doSomething();  
37.	    }  
38.	}  
39.	class ObjectStruture {  
40.	    public static List<Element> getList(){  
41.	        List<Element> list = new ArrayList<Element>();  
42.	        Random ran = new Random();  
43.	        for(int i=0; i<10; i++){  
44.	            int a = ran.nextInt(100);  
45.	            if(a>50){  
46.	                list.add(new ConcreteElement1());  
47.	            }else{  
48.	                list.add(new ConcreteElement2());  
49.	            }  
50.	        }  
51.	        return list;  
52.	    }  
53.	}  
54.	  
55.	public class Client {  
56.	    public static void main(String[] args){  
57.	        List<Element> list = ObjectStruture.getList();  
58.	        for(Element e: list){  
59.	            e.accept(new Visitor());  
60.	        }  
61.	    }  
62.	}  

Ventajas y desventajas del modo visitante

  1. Cumplimiento del principio de responsabilidad única: en cualquier escenario donde se aplique el modelo de visitante, las operaciones en la clase de elemento que deban encapsularse en el visitante deben ser operaciones que tengan poco que ver con la clase de elemento en sí y sean volátiles. El uso del modelo de visitante por un lado se ajusta a la responsabilidad única Principio, por otro lado, debido a que las operaciones encapsuladas generalmente son modificables, cuando ocurren cambios, la extensión de la parte cambiada se puede lograr sin cambiar la clase del elemento en sí.
  2. Buena escalabilidad: las clases de elementos se pueden extender a diferentes operaciones aceptando diferentes visitantes.

Escenarios de uso del modo visitante

Si hay algunas operaciones que son irrelevantes (o están débilmente relacionadas) con el objeto en un objeto, para evitar que estas operaciones contaminen el objeto, puede usar el patrón de visitante para encapsular estas operaciones en el visitante.

Si existen operaciones similares en un grupo de objetos, para evitar una gran cantidad de códigos repetidos, estas operaciones repetidas también pueden encapsularse en el visitante.

Sin embargo, el modelo de visitante no es tan perfecto, también tiene un defecto fatal: es difícil agregar nuevas clases de elementos. A través del código del patrón de visitante, podemos ver que en la clase de visitante, cada clase de elemento tiene su método de procesamiento correspondiente, es decir, cada clase de elemento adicional necesita modificar la clase de visitante (incluida la clase de visitante Subclase o clase de implementación), es bastante difícil de modificar. En otras palabras, el modo de visitante debe usarse con precaución cuando el número de clases de elementos es incierto. Por lo tanto, el modelo de visitante es más adecuado para la reconstrucción de funciones existentes. Por ejemplo, se ha determinado la función básica de un proyecto, y los datos del tipo de elemento se han determinado básicamente y no cambiarán. Lo que cambiará es solo la correlación dentro de estos elementos. Operación, en este momento, podemos usar el modo visitante para refactorizar el código original, de modo que podamos modificar la función original sin modificar cada clase de elemento.

 

Supongo que te gusta

Origin blog.csdn.net/sinat_37138973/article/details/88636394
Recomendado
Clasificación