Combination mode of design mode learning

Combination mode

Combine multiple objects to form a tree structure to represent a hierarchical structure with a part-whole relationship. The combined mode allows the client to treat single objects and combined objects uniformly, which is an object structure mode

Class Diagram

Insert picture description here

achieve

Component, an abstract component, can be an interface or an abstract class. Interfaces are declared for leaf components and container component objects. This role can contain declarations and implementations of behaviors shared by all subclasses.
The abstract component defines methods to access and manage its sub-components, such as adding, deleting, and obtaining sub-components

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

Leaf leaf components implement the behavior defined in abstract components. In addition, leaf components can no longer contain sub-components. Therefore, exception handling or error prompts need to be provided when implementing sub-component management and access methods in leaf components.

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() {
    
    
        //叶子构件具体业务方法的实现
    }
}

The container component provides a collection for storing sub-nodes, and realizes the behaviors defined in the abstract component, including methods for accessing and managing sub-components

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

Applications

A software company wants to develop an antivirus (Antivirus) software that can disinfect a folder (Folder) or a specified file (File). The anti-virus software can also provide different anti-virus methods for different types of files according to the characteristics of various types of files. For example, the anti-virus methods of image files (ImageFile) and text files (TextFile) are different. Now use the combined mode to design the overall framework of the anti-virus software.
Insert picture description here

Code

Abstract file, as an abstract component class

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

}

Leaf component

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 + "'进行杀毒");

	}

}

Folder class, container component class

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

	}

}

Client

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

Operation result
Insert picture description here
If you need to change the operation node, such as only need to disinfect the text folder, just change folder1.killVirus() to folder3.killVirus()

Transparent combination mode and safe combination mode

Transparent combination mode

In the transparent composition mode, all methods for managing member objects are declared in the abstract component Component, such as add, remove, etc. The advantage of this is to ensure that all component classes have the same interface. From the perspective of the client, the methods provided by the leaf object and the container object are consistent, and the client can treat all objects consistently

The disadvantage of the transparent combination mode is that it is not safe enough, because the leaf object and the container object are essentially different, and the leaf object cannot have the next level of objects, so the add method provided for it is meaningless, and you need to provide the corresponding Error handling code

Safe combination mode

In the safe mode, the abstract component does not declare any method for managing member objects, but declares and implements it in the Composite class. This approach is safe, but because it is not transparent enough, there are no more leaf classes and container classes. The same interface, the client's call needs to be judged accordingly

Advantages and disadvantages of combined mode

Advantages:
(1) It is possible to clearly define hierarchical complex objects, representing all or part of the object's hierarchy, which allows the client to ignore the differences in levels and facilitates the control of the entire hierarchy.
(2) The client can be used consistently A composite structure or a single object in it, you don’t have to care about whether you are dealing with a single object or the entire composite structure, which simplifies the client code.
(3) It is convenient to add new container components and leaf components.
Disadvantage: It
is difficult to add new components to the container. Component types in

Applicable environment

(1) In a hierarchical structure with whole and part, it is hoped to ignore the difference between whole and part in a way, and the client can treat them uniformly.
(2) A tree structure needs to be processed in a system developed with an object-oriented language
(3) Leaf objects and container objects can be separated in a system, and their types are not fixed, some new types need to be added

reference

Java design patterns

Big talk design pattern

Guess you like

Origin blog.csdn.net/qq_43610675/article/details/111523219