Modo de combinación de aprendizaje del modo de diseño

Modo de combinación

Combine varios objetos para formar una estructura de árbol para representar una estructura jerárquica con una relación de parte y todo. El modo combinado permite al cliente tratar objetos individuales y objetos combinados de manera uniforme, que es un modo de estructura de objeto

Diagrama de clase

Inserte la descripción de la imagen aquí

lograr

Componente, un componente abstracto, puede ser una interfaz o una clase abstracta. Las interfaces se declaran para componentes hoja y objetos de componente contenedor. Este rol puede contener declaraciones e implementaciones de comportamientos compartidos por todas las subclases.
El componente abstracto define métodos para acceder y administrar sus subcomponentes, como agregar, eliminar y obtener subcomponentes.

package design.composite.realize;

/*
 *
 *@author:zzf
 *@time:2020-12-22
 *
 */
public abstract class Component {
    
    
   public abstract void add(Component c);
   public abstract void remove(Component c);
   public abstract Component getChild(int i);
   public abstract void operation();
}

Los componentes hoja implementan el comportamiento definido en los componentes abstractos. Además, los componentes hoja ya no pueden contener subcomponentes. Por lo tanto, es necesario proporcionar manejo de excepciones o avisos de error al implementar métodos de acceso y gestión de subcomponentes en componentes hoja.

package design.composite.realize;

/*
 *
 *@author:zzf
 *@time:2020-12-22
 *
 */
public class Leaf extends Component {
    
    
    @Override
    public void add(Component c) {
    
    
        //异常或错误提示
    }

    @Override
    public void remove(Component c) {
    
    
        //异常或错误提示
    }

    @Override
    public Component getChild(int i) {
    
    
        //异常或错误提示
        return null;
    }

    @Override
    public void operation() {
    
    
        //叶子构件具体业务方法的实现
    }
}

El componente contenedor proporciona una colección para almacenar subnodos y realiza los comportamientos definidos en el componente abstracto, incluidos los métodos para acceder y administrar subcomponentes.

package design.composite.realize;

import java.util.ArrayList;

/*
 *
 *@author:zzf
 *@time:2020-12-22
 *
 */
public class Composite extends Component {
    
    
    private ArrayList<Component> list=new ArrayList<>();
    @Override
    public void add(Component c) {
    
    
        list.add(c);
    }

    @Override
    public void remove(Component c) {
    
    
        list.remove(c);
    }

    @Override
    public Component getChild(int i) {
    
    
        return (Component)list.get(i);
    }

    @Override
    public void operation() {
    
    
        //容器构建具体业务方法的实现,将递归调用成员构件的业务方法
        for (Object obj:list){
    
    
            ((Component)obj).operation();
        }
    }
}

Aplicaciones

Una empresa de software desea desarrollar un software antivirus (Antivirus) que pueda desinfectar una carpeta (Carpeta) o un archivo específico (Archivo). El software antivirus también puede proporcionar diferentes métodos antivirus para diferentes tipos de archivos de acuerdo con las características de varios tipos de archivos. Por ejemplo, los métodos antivirus de archivos de imagen (ImageFile) y archivos de texto (TextFile) son diferentes . Ahora use el modo combinado para diseñar el marco general del software antivirus.
Inserte la descripción de la imagen aquí

Código

Archivo abstracto, como clase de componente abstracto

package design.composite;

public abstract class AbstractFile {
    
    

	public abstract void add(AbstractFile file);

	public abstract void remove(AbstractFile file);

	public abstract AbstractFile getChild(int i);

	public abstract void killVirus();

}

Componente de hoja

package design.composite;

public class ImageFile extends AbstractFile {
    
    

	private String name;

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

	@Override
	public void add(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public void remove(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public AbstractFile getChild(int i) {
    
    
		System.out.println("对不起,不支持该方法!");
		return null;
	}

	@Override
	public void killVirus() {
    
    
		// 模拟杀毒
		System.out.println("----对图像文件'" + name + "'进行杀毒");

	}

}

package design.composite;

public class TextFile extends AbstractFile {
    
    

	private String name;

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

	@Override
	public void add(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public void remove(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public AbstractFile getChild(int i) {
    
    
		System.out.println("对不起,不支持该方法!");
		return null;
	}

	@Override
	public void killVirus() {
    
    
		// 模拟杀毒
		System.out.println("----对文本文件'" + name + "'进行杀毒");

	}

}

package design.composite;

public class VedioFile extends AbstractFile {
    
    

	private String name;

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

	@Override
	public void add(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public void remove(AbstractFile file) {
    
    
		System.out.println("对不起,不支持该方法!");

	}

	@Override
	public AbstractFile getChild(int i) {
    
    
		System.out.println("对不起,不支持该方法!");
		return null;
	}

	@Override
	public void killVirus() {
    
    
		// 模拟杀毒
		System.out.println("----对文本文件'" + name + "'进行杀毒");

	}

}

Clase de carpeta, clase de componente de contenedor

package design.composite;

import java.util.ArrayList;

public class Folder extends AbstractFile {
    
    

	// 定义集合fileList,用于存储AbstractFile类型的成员
	private ArrayList<AbstractFile> fileList = new ArrayList<>();
	private String name;

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

	@Override
	public void add(AbstractFile file) {
    
    
		fileList.add(file);

	}

	@Override
	public void remove(AbstractFile file) {
    
    
		fileList.remove(file);

	}

	@Override
	public AbstractFile getChild(int i) {
    
    
		return (AbstractFile) fileList.get(i);
	}

	@Override
	public void killVirus() {
    
    
		System.out.println("****对文件夹'" + name + "'进行杀毒");// 模拟杀毒
		// 递归调用成员构件的killVirus方法
		for (Object obj : fileList) {
    
    
			((AbstractFile) obj).killVirus();
		}

	}

}

Cliente

package design.composite;

public class Client {
    
    

	public static void main(String[] args) {
    
    
		// 针对抽象构件编程
		AbstractFile file1, file2, file3, file4, file5, folder1, folder2, folder3, folder4;

		folder1 = new Folder("Sunny的资料");
		folder2 = new Folder("图像文件");
		folder3 = new Folder("文本文件");
		folder4 = new Folder("视频文件");

		file1 = new ImageFile("小龙女.jpg");
		file2 = new ImageFile("张无忌.gif");
		file3 = new TextFile("九阴真经.txt");
		file4 = new TextFile("葵花宝典.txt");
		file5 = new VedioFile("笑傲江湖.rmvb");

		folder2.add(file1);
		folder2.add(file2);
		folder3.add(file3);
		folder3.add(file4);
		folder4.add(file5);
		folder1.add(folder2);
		folder1.add(folder3);
		folder1.add(folder4);

		// 从"Sunny的资料"结点开始进行杀毒
		folder1.killVirus();
	}
}

Resultado de la operación
Inserte la descripción de la imagen aquí
Si necesita cambiar el nodo de operación, por ejemplo, solo necesita desinfectar la carpeta de texto, simplemente cambie folder1.killVirus () a folder3.killVirus ()

Modo de combinación transparente y modo de combinación seguro

Modo de combinación transparente

En el modo de composición transparente, todos los métodos para administrar objetos miembro se declaran en el componente abstracto Component, como agregar, eliminar, etc. La ventaja de esto es garantizar que todas las clases de componentes tengan la misma interfaz. Desde la perspectiva del cliente, los métodos proporcionados por el objeto hoja y el objeto contenedor son coherentes, y el cliente puede tratar todos los objetos de forma coherente.

La desventaja del modo de combinación transparente es que no es lo suficientemente seguro, porque el objeto hoja y el objeto contenedor son esencialmente diferentes, y el objeto hoja no puede tener el siguiente nivel de objetos, por lo que el método de adición proporcionado no tiene sentido, y debe proporcionar el código de manejo de errores correspondiente

Modo de combinación segura

En el modo seguro, el componente abstracto no declara ningún método para administrar objetos miembro, pero lo declara e implementa en la clase Composite. Este enfoque es seguro, pero debido a que no es lo suficientemente transparente, no hay más clases hoja ni clases contenedoras. . La misma interfaz, la llamada del cliente debe juzgarse en consecuencia

Ventajas y desventajas del modo combinado

Ventajas:
(1) Es posible definir claramente objetos complejos jerárquicos, que representan la totalidad o parte de la jerarquía del objeto, lo que permite al cliente ignorar las diferencias de niveles y facilita el control de toda la jerarquía.
(2) El cliente puede ser utilizado de forma coherente Una estructura compuesta o un solo objeto en ella, no tiene que preocuparse por si está tratando con un solo objeto o con la estructura compuesta completa, lo que simplifica el código del cliente.
(3) Es conveniente agregar un nuevo contenedor componentes y componentes de hoja.
Desventaja:
es difícil agregar nuevos componentes al contenedor. Tipos de componentes en

Entorno aplicable

(1) En una estructura jerárquica con todo y parte, se espera ignorar la diferencia entre todo y parte de alguna manera, y el cliente puede tratarlos de manera uniforme.
(2) Una estructura de árbol necesita ser procesada en un sistema desarrollado con un lenguaje orientado a objetos
(3) Los objetos hoja y los objetos contenedores se pueden separar en un sistema, y ​​sus tipos no son fijos, es necesario agregar algunos tipos nuevos

referencia

Patrones de diseño de Java

Patrón de diseño Big Talk

Supongo que te gusta

Origin blog.csdn.net/qq_43610675/article/details/111523219
Recomendado
Clasificación