Modo de combinación de "Patrón de diseño"

1. Prefacio _

Debemos estar muy familiarizados con las dos imágenes anteriores. Ambas imágenes pueden considerarse como una estructura de archivos. A esta estructura la llamamos estructura de árbol . En la estructura de datos, sabemos que podemos atravesar todo el árbol llamando a un determinado método. Cuando encontramos un nodo hoja, podemos realizar operaciones relacionadas en el nodo hoja. Podemos entender este árbol como un contenedor grande, que contiene muchos objetos miembro, que pueden ser objetos contenedor u objetos hoja. Sin embargo, debido a las diferencias funcionales entre los objetos contenedores y los objetos hoja, debemos distinguir entre los objetos contenedor y los objetos hoja durante el uso. Sin embargo, esto traerá problemas innecesarios a los clientes. Como cliente, siempre espera poder tratar los objetos contenedores. y hojas de objetos consistentemente. Ésta es la motivación del diseño del patrón combinado. 

2. ¿Qué es el modo combinado?

El modo de combinación combina recursivamente objetos hoja y objetos contenedor para formar una estructura de árbol para representar la jerarquía "parte-todo", lo que permite a los usuarios usar objetos individuales y objetos combinados de manera consistente, y puede manejar combinaciones como objetos hoja Objetos sin distinción, lo que permite al usuario programas que deben desacoplarse de la estructura interna de elementos complejos.

Lo más importante del patrón de combinación es que los objetos de hoja y los objetos de combinación implementan la misma clase de construcción abstracta. Puede representar tanto objetos de hoja como objetos contenedor. Los clientes solo necesitan programar para esta clase de construcción abstracta. Así es como el patrón de combinación puede La razón por la que los nodos hoja y los nodos objeto se procesan de forma coherente.

A través del modo combinado, la estructura jerárquica de objetos complejos se puede definir claramente: los objetos hoja se pueden combinar en objetos contenedores más complejos y los objetos contenedores se pueden combinar, de modo que la recursividad continua forme una estructura de árbol compleja; al mismo tiempo, en el modo combinado También es más fácil agregar nuevas construcciones de objetos y el cliente no tiene que cambiar el código original debido a la adición de nuevos componentes de objetos.

La imagen en la parte superior del artículo muestra el sistema de archivos de la computadora. El sistema de archivos se compone de archivos y directorios. El directorio también puede contener archivos o directorios. El sistema de archivos de la computadora está organizado mediante una estructura recursiva, que es muy adecuada para tales estructuras de datos Utilice el modo combinado.

3. Diagrama de estructura UML

El modo combinado incluye principalmente los siguientes roles:

  • Componente: construye clases de forma abstracta, los objetos en la composición declaran interfaces y, cuando corresponde, implementan el comportamiento predeterminado de las interfaces comunes a todas las clases. Declare una interfaz para acceder y administrar los subcomponentes del componente. 
  • Hoja: objeto hoja. Los nodos hoja no tienen nodos secundarios. 
  • Compuesto: objeto contenedor, que define el comportamiento de los nodos de rama y se utiliza para almacenar subcomponentes e implementar operaciones relacionadas con los subcomponentes en la interfaz del Componente, como agregar (agregar) y eliminar (eliminar).

Desde la estructura del patrón, podemos ver que tanto los nodos hoja como los objetos contenedores implementan la interfaz Componente, que también es la clave para tratar los objetos hoja y los objetos contenedores de manera consistente. 

3. Implementación del código

3.1 Implementación del código 1

En el sistema de archivos, puede haber archivos en muchos formatos, como imágenes, archivos de texto, archivos de video, etc. Los métodos de exploración de estos archivos de diferentes formatos son diferentes. Al mismo tiempo, explorar la carpeta es explorar los archivos en el carpeta. Pero para los clientes, todos son archivos de exploración y no hay diferencia entre los dos. Ahora solo se utiliza el modo combinado para simular la exploración de archivos. Diagrama de estructura UML:

La primera es la clase de archivo: File.java

public abstract class File {
    String name;
    
    public File(String name){
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public abstract void display();
}

Luego está la clase de carpeta: Folder.java, que contiene tres métodos para agregar, eliminar y explorar archivos.

public class Folder extends File{
    private List<File> files;
    
    public Folder(String name){
        super(name);
        files = new ArrayList<File>();
    }
    
    /**
     * 浏览文件夹中的文件
     */
    public void display() {
        for(File file : files){
            file.display();
        }
    }
    
    /**
     * @desc 向文件夹中添加文件
     * @param file
     * @return void
     */
    public void add(File file){
        files.add(file);
    }
    
    /**
     * @desc 从文件夹中删除文件
     * @param file
     * @return void
     */
    public void remove(File file){
        files.remove(file);
    }
}

Luego hay tres clases de archivos: TextFile.java, ImageFile.java, VideoFile.java

public class TextFile extends File{
 
    public TextFile(String name) {
        super(name);
    }
 
    public void display() {
        System.out.println("这是文本文件,文件名:" + super.getName());
    }
}
 
public class ImagerFile extends File{
 
    public ImagerFile(String name) {
        super(name);
    }
 
    public void display() {
        System.out.println("这是图像文件,文件名:" + super.getName());
    }
}
 
public class VideoFile extends File{
 
    public VideoFile(String name) {
        super(name);
    }
 
    public void display() {
        System.out.println("这是影像文件,文件名:" + super.getName());
    }
}

Finalmente el cliente:

public class Client {
    public static void main(String[] args) {
        /**
         * 我们先建立一个这样的文件系统
         *                  总文件
         *                  
         *   a.txt    b.jpg                   c文件夹              
         *                      c_1.text  c_1.rmvb    c_1.jpg                                                      
         */ 
        //总文件夹
        Folder zwjj = new Folder("总文件夹");
        //向总文件夹中放入三个文件:1.txt、2.jpg、1文件夹
        TextFile aText= new TextFile("a.txt");
        ImagerFile bImager = new ImagerFile("b.jpg");
        Folder cFolder = new Folder("C文件夹");
        
        zwjj.add(aText);
        zwjj.add(bImager);
        zwjj.add(cFolder);
        
        //向C文件夹中添加文件:c_1.txt、c_1.rmvb、c_1.jpg 
        TextFile cText = new TextFile("c_1.txt");
        ImagerFile cImage = new ImagerFile("c_1.jpg");
        VideoFile cVideo = new VideoFile("c_1.rmvb");
        
        cFolder.add(cText);
        cFolder.add(cImage);
        cFolder.add(cVideo);
        
        //遍历C文件夹
        cFolder.display();
        //将c_1.txt删除
        cFolder.remove(cText);
        System.out.println("-----------------------");
        cFolder.display();
    }
}

resultado de la operación:

3.2 Implementación del código 2

Ejemplo de código:  

package com.mashibing.dp.composite;

import java.util.ArrayList;
import java.util.List;

abstract class Node {
    abstract public void p();
}

class LeafNode extends Node {
    String content;
    public LeafNode(String content) {this.content = content;}

    @Override
    public void p() {
        System.out.println(content);
    }
}

class BranchNode extends Node {
    List<Node> nodes = new ArrayList<>();

    String name;
    public BranchNode(String name) {this.name = name;}

    @Override
    public void p() {
        System.out.println(name);
    }

    public void add(Node n) {
        nodes.add(n);
    }
}


public class Main {
    public static void main(String[] args) {

        BranchNode root = new BranchNode("root");
        BranchNode chapter1 = new BranchNode("chapter1");
        BranchNode chapter2 = new BranchNode("chapter2");
        Node r1 = new LeafNode("r1");
        Node c11 = new LeafNode("c11");
        Node c12 = new LeafNode("c12");
        BranchNode b21 = new BranchNode("section21");
        Node c211 = new LeafNode("c211");
        Node c212 = new LeafNode("c212");

        root.add(chapter1);
        root.add(chapter2);
        root.add(r1);
        chapter1.add(c11);
        chapter1.add(c12);
        chapter2.add(b21);
        b21.add(c211);
        b21.add(c212);

        tree(root, 0);

    }

    static void tree(Node b, int depth) {
        for(int i=0; i<depth; i++) System.out.print("--");
        b.p();

        if(b instanceof BranchNode) {
            for (Node n : ((BranchNode)b).nodes) {
                tree(n, depth + 1);
            }
        }
    }
}

resultado de la operación:

Artículo de referencia:  Tipo estructural de patrón de diseño Java: patrón combinado_blog-CSDN de Zhang Weipeng

Supongo que te gusta

Origin blog.csdn.net/m0_50370837/article/details/126304581
Recomendado
Clasificación