组合模式
介绍:
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
结构:
1、Component (抽象构件):
是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
2、Leaf(叶子构件):
在组合中表示叶子结点对象,叶子结点没有子结点。
3、Composite(容器构件):
定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
模式实例之磁盘文件遍历器
用组合模式设计一个磁盘文件遍历器。要求可以输入不同的磁盘文件夹,遍历后输出该文件夹下的树形结构图。并画出相应的UML类图。
–利用gui的树控件可以弄出树形结构
package bridge;
//抽象构件类---既可代表文件夹,也可代表文件
public abstract class AbstractElement {
protected String name;//抽象构件名称
public AbstractElement(String name){
this.name = name;
}
//抽象方法,子类皆需实现
public abstract String show();
public void addElement(AbstractElement element){}
}
package bridge;
//叶子构件类--文件类
public class Filer extends AbstractElement{
public Filer(String name) {
super(name);
this.name = name;
}
@Override
public String show() {
return name;
}
}
package bridge;
import java.util.ArrayList;
import java.util.List;
public class Folder extends AbstractElement {
List<AbstractElement> list = new ArrayList<AbstractElement>();
public Folder(String name) {
super(name);
this.name = name;
}
@Override
public String show() {
for (AbstractElement abstractElement : list) {
abstractElement.show();
}
return name;
}
public void addElement(AbstractElement element){
list.add(element);
}
}
package bridge;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class Client extends JFrame implements ActionListener{
private JPanel panel;
private JLabel label1,label2;
private JTextField tf;
private JTree tree;//目录树控件
private JButton button;
DefaultMutableTreeNode root;
public Client(){
super("磁盘文件遍历器");
panel = new JPanel();
label1 = new JLabel("请输入磁盘路径,格式类似“D:\\test”,");
label2 = new JLabel("不能单独输入c盘或d盘等,只能输入某个盘的文件夹");
tf = new JTextField(20);
button = new JButton("确定");
button.addActionListener(this);
label1.setBounds(80, 10, 300, 20);//设置组件位置
label2.setBounds(80, 40, 350, 20);
tf.setBounds(80, 60, 200, 30);
button.setBounds(150, 100, 80, 40);
panel.setLayout(null);
panel.add(tf);
panel.add(label1);
panel.add(label2);
panel.add(button);
this.setSize(420, 600);
this.getContentPane().add(panel);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口即结束程序
}
@Override
//点击“确定”按钮,生成目录
public void actionPerformed(ActionEvent e) {
AbstractElement folder = new Folder(tf.getText().toString());//获取输入的路径
root = new DefaultMutableTreeNode(folder.show());
tree = new JTree(root);
createTree(folder);
panel.setLayout(null);
panel.add(tree);
panel.remove(tf);
panel.remove(label1);
panel.remove(label2);
panel.remove(button);
tree.setShowsRootHandles(true);
tree.setRootVisible(true);
JScrollPane scrPane = new JScrollPane(tree);
add(scrPane);
}
public void createTree(AbstractElement folder){
File f = new File(folder.name);
File[] roots = f.listFiles();
for (File file : roots) {
if(file.isFile()){
Filer filer = new Filer(file.getAbsolutePath());
DefaultMutableTreeNode node = new DefaultMutableTreeNode(filer.show());
root.add(node);
}
if(file.isDirectory()){
Folder folder1 = new Folder(file.getAbsolutePath());
folder.addElement(folder1);
DefaultMutableTreeNode node = new DefaultMutableTreeNode(folder1.show());
root.add(node);
createTree(folder1);//递归生成目录
}
}
}
public static void main(String[] args){
Client client = new Client();
}
}