Modo de combinação de "Design Pattern"

1. Prefácio _

Devemos estar bem familiarizados com as duas imagens acima. Ambas as imagens podem ser consideradas como uma estrutura de arquivo. Chamamos essa estrutura de estrutura em árvore . Na estrutura de dados, sabemos que podemos percorrer toda a árvore chamando um determinado método.Quando encontramos um nó folha, podemos realizar operações relacionadas no nó folha. Podemos entender esta árvore como um grande contêiner, que contém muitos objetos membros.Esses objetos membros podem ser objetos contêineres ou objetos folha. No entanto, devido às diferenças funcionais entre objetos contêiner e objetos folha, devemos distinguir entre objetos contêiner e objetos folha durante o uso. No entanto, isso trará problemas desnecessários aos clientes. Como cliente, ele sempre espera poder tratar objetos contêineres e objetos folha consistentemente. Esta é a motivação do design do padrão de combinação. 

2. Qual é o modo de combinação?

O modo de combinação combina recursivamente objetos folha e objetos contêiner para formar uma estrutura de árvore para representar a hierarquia "parte-todo", permitindo que os usuários usem objetos únicos e objetos combinados de forma consistente, e podem lidar com combinações como objetos folha. Objetos sem distinção, permitindo ao usuário programas a serem dissociados da estrutura interna de elementos complexos.

A coisa mais crítica sobre o padrão de combinação é que objetos folha e objetos combinados implementam a mesma classe de construção abstrata. Ele pode representar objetos folha e objetos contêiner. Os clientes só precisam programar para esta classe de construção abstrata. É assim que o padrão de combinação pode A razão pela qual os nós folha e os nós de objeto são processados ​​de forma consistente.

Através do modo de combinação, a estrutura hierárquica de objetos complexos pode ser claramente definida. Os objetos folha podem ser combinados em objetos contêineres mais complexos e os objetos contêineres podem ser combinados, de modo que a recursão contínua forme uma estrutura de árvore complexa; ao mesmo tempo, em o modo de combinação Também é mais fácil adicionar novas construções de objetos e o cliente não precisa alterar o código original devido à adição de novos componentes de objetos.

A imagem no topo do artigo mostra o sistema de arquivos do computador. O sistema de arquivos é composto por arquivos e diretórios. O diretório também pode conter arquivos ou diretórios. O sistema de arquivos do computador é organizado usando uma estrutura recursiva, que é muito adequada para tal estruturas de dados. Use o modo de combinação.

3. Diagrama de estrutura UML

O modo de combinação inclui principalmente as seguintes funções:

  • Componente: constrói classes abstratamente, os objetos na composição declaram interfaces e, quando apropriado, implementam o comportamento padrão das interfaces comuns a todas as classes. Declare uma interface para acessar e gerenciar subcomponentes do componente. 
  • Folha: objeto folha. Os nós folha não possuem nós filhos. 
  • Composto: Objeto Container, que define o comportamento dos nós de ramificação e é usado para armazenar subcomponentes e implementar operações relacionadas aos subcomponentes na interface do Componente, como adicionar (adicionar) e excluir (remover).

A partir da estrutura padrão, podemos ver que tanto os nós folha quanto os objetos contêineres implementam a interface Component, que também é a chave para tratar objetos folha e objetos contêineres de forma consistente. 

3. Implementação de código

3.1. Implementação de código 1

No sistema de arquivos, pode haver arquivos em vários formatos, como imagens, arquivos de texto, arquivos de vídeo, etc. Os métodos de navegação desses arquivos de formatos diferentes são diferentes. Ao mesmo tempo, navegar na pasta é navegar nos arquivos no pasta. Mas para os clientes, eles são todos arquivos de navegação e não há diferença entre os dois. Agora apenas o modo de combinação é usado para simular a navegação de arquivos. Diagrama de estrutura UML:

A primeira é a classe do arquivo: 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();
}

Depois, há a classe de pasta: Folder.java, que contém três métodos para adicionar, excluir e navegar por arquivos.

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);
    }
}

Depois, existem três classes de arquivo: 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 o 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 da operação:

3.2. Implementação de código 2

Exemplo 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 da operação:

Artigo de referência:  Tipo estrutural de padrão de design Java: padrão de combinação_blog de Zhang Weipeng-blog CSDN

Acho que você gosta

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