Patrón de diseño (veinticuatro) patrón de visitantes

Patrón de visitante

1. ¿Cuál es el patrón de visitantes?

Patrón de visitante: Proporciona una representación de la operación que actúa sobre cada elemento en una estructura de objeto, nos permite definir nuevas operaciones que actúan sobre estos elementos sin cambiar la clase de cada elemento.
El patrón de visitante es un patrón de comportamiento de objeto.

¿Cómo proporcionar múltiples modos de operación diferentes para elementos en el mismo objeto de colección? El modelo de visitante es una solución que vale la pena considerar, puede resolver los problemas anteriores hasta cierto punto (resolver la mayoría de los problemas). El modo visitante puede proporcionar múltiples operaciones de acceso para diferentes tipos de elementos y puede agregar nuevas operaciones sin modificar el sistema original.

El patrón de visitante contiene dos componentes principales: visitante y elemento visitado, estos elementos visitados suelen tener diferentes tipos, y diferentes visitantes pueden realizar diferentes operaciones de visita sobre ellos. El modo visitante permite a los usuarios expandir las funciones del sistema sin modificar el sistema existente, agregando nuevas operaciones a estos diferentes tipos de elementos.

Cuando hay una estructura de objeto más compleja en el sistema, y ​​diferentes visitantes realizan diferentes operaciones en él, considere usar el patrón de visitante para el diseño.

2. Análisis de roles en el patrón de visitantes

Diagrama de estructura del modo visitante:
Modo visitante

  • Vistor (visitante abstracto): El visitante abstracto declara una operación de acceso para cada clase de elemento concreto ConcreteElement en la estructura del objeto. A partir del nombre o tipo de parámetro de esta operación, puede saber claramente el tipo de elemento específico al que se debe acceder. El visitante específico necesita implementar este método de operación, que define la operación de acceso a estos elementos.
  • ConcreteVisitor (visitante concreto): el visitante concreto implementa cada operación declarada por el visitante abstracto, y cada operación se utiliza para acceder a un tipo de elemento en la estructura del objeto.
  • Elemento (elemento abstracto): Los elementos abstractos son generalmente clases o interfaces abstractas, que definen un método accept (), que normalmente toma un visitante abstracto como parámetro.
  • ConcreteElement (elemento concreto): El elemento concreto implementa el método accept (). En el método accept (), se llama al método de acceso del visitante para completar la operación de un elemento.
  • ObjectStructure (estructura de objeto): la estructura de objeto es una colección de elementos, se utiliza para almacenar objetos de elemento y proporciona métodos para atravesar sus elementos internos. Puede implementarse en combinación con un modo de combinación, o puede ser un objeto de colección simple, como un objeto List o un objeto Set.

La estructura de objetos en el patrón de visitantes almacena diferentes tipos de objetos de elementos para que diferentes visitantes accedan.
El patrón de visitantes incluye dos estructuras jerárquicas:

  1. Uno es la jerarquía de visitantes, que proporciona visitantes abstractos y visitantes específicos,
  2. Uno es la jerarquía de elementos, que proporciona elementos abstractos y concretos.
    El mismo visitante puede acceder a diferentes elementos de diferentes maneras, y diferentes visitantes pueden acceder al mismo elemento de diferentes maneras.
    En el modo de visitante, agregar nuevos visitantes no necesita modificar el sistema original, y el sistema tiene una buena escalabilidad.
  • Los visitantes abstractos definen métodos para acceder a los objetos del elemento y, por lo general, proporcionan un método de acceso para cada tipo de objeto del elemento, y los visitantes específicos pueden implementar estos métodos de acceso.
    Estos métodos de acceso generalmente se nombran de dos maneras: una es para indicar directamente el tipo específico de objeto de elemento al que se accede en el nombre del método, como visitElementA (ElementA elementA), y la otra es nombrar uniformemente visit () y pass el tipo de parámetro Para definir una serie de métodos visit () sobrecargados. Por supuesto, si todos los visitantes tienen la misma operación de acceso a un determinado tipo de elemento, el código de operación se puede mover a la clase de visitante abstracto. El código típico es el siguiente:
abstract class Visitor {
    
    
	public abstract void visit(ConcreteElementA elementA);
	public abstract void visit(ConcreteElementB elementB);
	public void visit(ConcreteElementC elementC) {
    
    
		//元素ConcreteElementC操作代码
	}
}
  • Para la clase de elemento, generalmente se define un método accept () para aceptar el acceso de visitantes
interface Element {
    
    
	public void accept(Visitor visitor);
}

Este método pasa un parámetro del tipo de visitante abstracto, es decir, la programación para el visitante abstracto, no para el visitante específico. El tipo de visitante específico se determina cuando se ejecuta el programa y la visita () del objeto de visitante específico se llama Métodos implementan operaciones sobre objetos de elementos.
El método accept () se implementa en la subclase de la clase de elemento abstracto Element para aceptar visitas de visitantes. En la clase de elemento específico, también puede definir métodos comerciales específicos para diferentes tipos de elementos. El código típico es el siguiente:

class ConcreteElementA implements Element {
    
    
	public void accept(Visitor visitor) {
    
    
		visitor.visit(this);
	}
	
	public void operationA() {
    
    
		//业务方法
	}
}
  • La estructura del objeto es una colección, que se utiliza para almacenar objetos de elementos y aceptar el acceso de visitantes. El código típico es el siguiente:
class ObjectStructure{
    
    
	private ArrayList<Element> list = new ArrayList<Element>(); //定义一个集合用于存储元素对象
 
	public void accept(Visitor visitor) {
    
    
		Iterator i=list.iterator();
		while(i.hasNext()) {
    
    
			((Element)i.next()).accept(visitor); //遍历访问集合中的每一个元素
		}
	}
 
	public void addElement(Element element){
    
    
		list.add(element);
	}
 
	public void removeElement(Element element){
    
    
		list.remove(element);
	}

3. Ventajas y desventajas del modo visitante

ventaja:

  • Es muy conveniente agregar nuevas operaciones de acceso. Al usar el modo de visitante, agregar una nueva operación de visita significa agregar una nueva clase de visitante específica, que es fácil de implementar, no es necesario modificar el código fuente y se ajusta al "principio de apertura y cierre".
  • Concentre los comportamientos de acceso de objetos de elementos relacionados en un objeto de visitante en lugar de estar dispersos en clases de elementos individuales. Las responsabilidades de la clase son más claras, lo que favorece la reutilización de los elementos de la estructura del objeto. Varios visitantes diferentes pueden acceder a la misma estructura de objetos.
  • Permite a los usuarios definir operaciones que actúan sobre la jerarquía sin modificar la jerarquía de clases de elementos existente.

Desventajas:

  • Es difícil agregar nuevas clases de elementos. En el patrón de visitante, cada nueva clase de elemento agregada significa que se agrega una nueva operación abstracta al rol de visitante abstracto, y se agrega una operación específica correspondiente a cada clase de visitante específica, lo que viola el principio cerrado "abierto".
  • Destruye el paquete. El modelo de visitante requiere que el objeto de visitante acceda y llame a la operación de cada objeto de elemento, lo que significa que el objeto de elemento a veces debe exponer algunas de sus propias operaciones internas y estado interno, de lo contrario, el visitante no puede acceder a él.

Escena aplicable:

  • Una estructura de objeto contiene múltiples tipos de objetos y se espera realizar algunas operaciones que dependen de sus tipos específicos en estos objetos. Se proporciona una operación de acceso para cada tipo específico entre visitantes, y diferentes tipos de objetos pueden tener diferentes operaciones de acceso.
  • Es necesario realizar muchas operaciones diferentes y no relacionadas en los objetos en una estructura de objeto, y es necesario evitar que estas operaciones "contaminen" las clases de estos objetos, y no es deseable modificar estas clases al agregar nuevas operaciones. . El patrón de visitante nos permite centralizar las operaciones de visita relacionadas y definirlas en la clase de visitante. La estructura del objeto puede ser utilizada por múltiples clases de visitante diferentes, separando el objeto en sí de la operación de acceso del objeto.
  • La clase correspondiente al objeto en la estructura del objeto rara vez cambia, pero a menudo es necesario definir nuevas operaciones en la estructura del objeto.

4. Impresión práctica

El modelo de visitante se divide en dos niveles para organizar las clases, uno es la jerarquía de visitantes y el otro es la jerarquía de elementos.
La operación que se brinda es: un
mismo visitante puede acceder a diferentes elementos, por lo que estos elementos diferentes deben estar en una colección, el visitante debe recorrer la visita, es decir, la clase ObjectStructure; el
mismo elemento puede ser accedido por diferentes visitantes. En la implementación, se puede pasar al visitante en el parámetro del método del elemento, que es la clase Vistor;

5. Ejemplo de código

// 元素类
interface Employee {
    
    
    //接受一个抽象访问者访问
    void accept(Department handler); 
}

class FulltimeEmployee implements Employee {
    
    
    private String name;

    FulltimeEmployee(String name) {
    
    
        this.name = name;
    }

    @Override
    public void accept(Department handler) {
    
    
        //调用访问者的访问方法
        handler.visit(this);
    }
}

class ParttimeEmployee implements Employee {
    
    
    private String name;

    ParttimeEmployee(String name) {
    
    
        this.name = name;
    }

    @Override
    public void accept(Department handler) {
    
    
        //调用访问者的访问方法
        handler.visit(this);
    }
}

// 访问者类
abstract class Department {
    
    
    abstract void visit(FulltimeEmployee employee);
    abstract void visit(ParttimeEmployee employee);
}

// 财务部门访问者
class FADepartment extends Department {
    
    
    //实现财务部对全职员工的访问
    @Override
    public void visit(FulltimeEmployee employee) {
    
    
        System.out.println("财务部门访问全职员工的逻辑");
    }

    //实现财务部对兼职员工的访问
    @Override
    public void visit(ParttimeEmployee employee) {
    
    
        System.out.println("财务部门访问兼职员工的逻辑");
    }
}

// 元素集合类
class HRDepartment extends Department {
    
    
    //实现人力资源部对全职员工的访问
    @Override
    public void visit(FulltimeEmployee employee) {
    
    
        System.out.println("人力部门访问全职员工的逻辑");
    }

    //实现人力资源部对兼职员工的访问
    @Override
    public void visit(ParttimeEmployee employee) {
    
    
        System.out.println("人力部门访问兼职员工的逻辑");
    }
}

class EmployeeList {
    
    
    //定义一个集合用于存储员工对象
    private ArrayList<Employee> list = new ArrayList<Employee>();

    void addEmployee(Employee employee) {
    
    
        list.add(employee);
    }

    //访问者遍历访问元素
    void accept(Department handler) {
    
    
        for (Object obj : list) {
    
    
            ((Employee) obj).accept(handler);
        }
    }
}

    public static void main(String[] args) {
    
    
        EmployeeList list = new EmployeeList();
        Employee fte1, fte2, fte3, pte1, pte2;

        fte1 = new FulltimeEmployee("1");
        fte2 = new FulltimeEmployee("2");
        fte3 = new FulltimeEmployee("3");
        pte1 = new ParttimeEmployee("4");
        pte2 = new ParttimeEmployee("5");

        list.addEmployee(fte1);
        list.addEmployee(fte2);
        list.addEmployee(fte3);
        list.addEmployee(pte1);
        list.addEmployee(pte2);

        //  财务部门访问所有员工
        Department dep = new FADepartment();
        list.accept(dep);
    }

Supongo que te gusta

Origin blog.csdn.net/u014099894/article/details/85219137
Recomendado
Clasificación