设计模式--组合模式

设计模式--组合模式

1 概述


1.1 定义
组合模式(Composite Design)将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户端以一致的方式处理个别对象以及对象组合。

1.2 应用场景
维护和展示部分-整体的层次结构,如Unix中的树形文件系统。
客户端可以忽略复杂的层次结构,使用统一的方式去操作层次结构中的所有对象,也可以使用组合模式。
简单的可以说:树状结构并且其各个节点(根、枝、叶)有共同的行为,就可以使用组合模式。
1.3 类图
enter description here

 

组合模式涉及的角色如下:

  1. Component抽象组件角色:定义参加组合对象的方法(一些方法Leaf不实现)。
  2. Composite组合角色:作用是与Leaf(树叶)节点形成一个树形结构。
  3. Leaf叶子角色:是遍历的最小单位。

2 详解

 1 public abstract class Component {
 2     // 个体与整体都具有的行为
 3     public void operate(){
 4         System.out.println("Common operation");
 5     }
 6     // 添加一个叶子或者组合
 7     public abstract void add(Component component) throws UnsupportedOperationException;
 8 
 9     // 移除一个叶子或者组合
10     public abstract boolean remove(Component component) throws UnsupportedOperationException;
11 
12     // 获得其分支下的所有叶子和组合
13     public abstract List<Component> getChildren() throws UnsupportedOperationException;
14 }
15 
16 public class Composite extends Component {
17     // 容器构件
18     private List<Component> componentList = new ArrayList<>();
19 
20     @Override
21     public void add(Component component) throws UnsupportedOperationException {
22             componentList.add(component);
23     }
24 
25     @Override
26     public boolean remove(Component component) throws UnsupportedOperationException {
27         return componentList.remove(component);
28     }
29 
30     @Override
31     public List<Component> getChildren() throws UnsupportedOperationException {
32         return componentList;
33     }
34 }
35 
36 public class Leaf extends Component {
37     @Override
38     public void add(Component component) throws UnsupportedOperationException {
39         throw new UnsupportedOperationException();
40     }
41 
42     @Override
43     public boolean remove(Component component) throws UnsupportedOperationException {
44         throw new UnsupportedOperationException();
45     }
46 
47     @Override
48     public List<Component> getChildren() throws UnsupportedOperationException {
49         throw new UnsupportedOperationException();
50     }
51 }
52 
53 public class Client {
54     public static void main(String[] args) {
55         Component root = new Composite();
56         Component brance = new Composite();
57         Component leaf = new Leaf();
58         root.add(brance);
59         brance.add(leaf);
60     }
61     // 递归遍历该树
62     public static void display(Component root) {
63         for(Component component : root.getChildren()) {
64             // 树枝节点
65             if(component instanceof Composite) {
66                 display(component);
67             }else {
68                 // 叶子节点
69                 component.operate();
70             }
71         }
72     }
73 }

3 应用

简单的模拟unix的文件系统

  1 public abstract class IFile {
  2     private String name;
  3     // 父类IFile
  4     private IFile parentIFile;
  5 
  6     IFile(String name) {
  7         this.name = name;
  8     }
  9 
 10     public String getName(){
 11         return name;
 12     }
 13 
 14     // 删除其自己
 15     public abstract boolean remove();
 16 
 17     // 获得其分支文件或者文件名
 18     public abstract IFile getIFile(String name) throws UnsupportedOperationException;
 19 
 20     // 创建文件
 21     public abstract void createFile(String name) throws UnsupportedOperationException;
 22 
 23     // 创建文件夹
 24     public abstract void createFolder(String name) throws UnsupportedOperationException;
 25 
 26     // 删除其分支文件
 27     public abstract boolean deleteFile(String name) throws UnsupportedOperationException;
 28 
 29     // 删除其分支文件夹
 30     public abstract boolean deleteFolder(String name) throws UnsupportedOperationException;
 31 
 32     // 获得其分支的文件或文件夹
 33     public abstract Set<IFile> getChildren() throws UnsupportedOperationException;
 34 
 35     // 设置父类文件
 36     public void setParentIFile(IFile parentIFile) {
 37         this.parentIFile = parentIFile;
 38     }
 39 
 40     // 获得父类文件
 41     public IFile getParentIFile() {
 42         return parentIFile;
 43     }
 44 
 45     @Override
 46     public boolean equals(Object obj) {
 47         if(obj == this) {
 48             return true;
 49         }
 50         if(obj instanceof IFile) {
 51             IFile iFile = (IFile) obj;
 52             return Objects.equals(iFile.getName(), getName());
 53         }
 54         return false;
 55     }
 56 
 57     @Override
 58     public int hashCode() {
 59         return name.hashCode();
 60     }
 61 
 62     @Override
 63     public String toString() {
 64         return name;
 65     }
 66 }
 67 
 68 public class Folder extends IFile {
 69     private Set<IFile> files = new HashSet<>();
 70 
 71     Folder(String name) {
 72         super(name);
 73     }
 74 
 75     @Override
 76     public boolean remove() {
 77         System.out.println("删除文件夹: " + getName());
 78         IFile parent = getParentIFile();
 79         return parent.deleteFolder(getName());
 80     }
 81 
 82     @Override
 83     public IFile getIFile(String name) throws UnsupportedOperationException {
 84         for(IFile iFile : files) {
 85             if(iFile.getName().equals(name)) {
 86                 return iFile;
 87             }
 88         }
 89         return null;
 90     }
 91 
 92     @Override
 93     public void createFile(String name) throws UnsupportedOperationException {
 94         IFile file = new File(name);
 95         file.setParentIFile(this);
 96         files.add(file);
 97     }
 98 
 99     @Override
100     public void createFolder(String name) throws UnsupportedOperationException {
101         IFile fileFolder = new Folder(name);
102         fileFolder.setParentIFile(this);
103         files.add(fileFolder);
104     }
105 
106     @Override
107     public boolean deleteFile(String name) throws UnsupportedOperationException {
108         return files.remove(new File(name));
109     }
110 
111     @Override
112     public boolean deleteFolder(String name) throws UnsupportedOperationException {
113         return files.remove(new Folder(name));
114     }
115 
116     @Override
117     public Set<IFile> getChildren() throws UnsupportedOperationException {
118         return files;
119     }
120 }
121 
122 public class File extends IFile {
123 
124     File(String name) {
125         super(name);
126     }
127 
128     @Override
129     public boolean remove() {
130         System.out.println("删除文件夹: " + getName());
131         IFile parent = getParentIFile();
132         return parent.deleteFile(getName());
133     }
134 
135     @Override
136     public void createFile(String name) throws UnsupportedOperationException {
137         throw new UnsupportedOperationException();
138     }
139 
140     @Override
141     public void createFolder(String name) throws UnsupportedOperationException {
142         throw new UnsupportedOperationException();
143     }
144 
145     @Override
146     public boolean deleteFile(String name) throws UnsupportedOperationException {
147         throw new UnsupportedOperationException();
148     }
149 
150     @Override
151     public boolean deleteFolder(String name) throws UnsupportedOperationException {
152         throw new UnsupportedOperationException();
153     }
154 
155     @Override
156     public Set<IFile> getChildren() throws UnsupportedOperationException {
157         throw new UnsupportedOperationException();
158     }
159 
160     @Override
161     public IFile getIFile(String name) throws UnsupportedOperationException {
162         throw new UnsupportedOperationException();
163     }
164 }
165 
166 public class Client {
167     public static void main(String[] args) {
168         IFile root = new Folder("/");
169         root.createFolder("user");
170         root.createFolder("net");
171         root.createFile("root.txt");
172 
173         IFile user = root.getIFile("user");
174         user.createFolder("picture");
175         user.createFolder("music");
176         IFile picture = user.getIFile("picture");
177         picture.createFile("flower.png");
178         picture.createFile("book.png");
179         IFile music = user.getIFile("music");
180         music.createFile("hello.mp3");
181 
182         IFile net = root.getIFile("net");
183         net.createFolder("config");
184         net.createFile("setting.txt");
185 
186         display(null, root);
187     }
188     // 递归遍历
189     public static void display(String prefix, IFile root) {
190         if(prefix == null) {
191             prefix = "";
192         }
193         System.out.println(prefix + root);
194         for(IFile iFile : root.getChildren()) {
195             if(iFile instanceof Folder) {
196                 display(prefix + "--", iFile);
197             }
198             if(iFile instanceof File) {
199                 System.out.println(prefix + "--" + iFile);
200             }
201         }
202     }
203 }output:
204 /
205 --root.txt
206 --net
207 ----setting.txt
208 ----config
209 --user
210 ----music
211 ------hello.mp3
212 ----picture
213 ------flower.png
214 ------book.png
View Code
posted @ 2017-03-29 01:05  默默的看雨下  阅读(127)  评论(0编辑  收藏  举报