组合模式
定义:将对象组合成树形结构以表示 ‘ 部分-整体 ’ 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
简单理解,就是,需求中,有部分构成整体的逻辑,然后在代码中用树状结构去实现需求。
比如我们eclipse中项目的展示图形就是典型的树状结构展示。只不过,这个树是朝右长的。
可以类比一下这个图:
案例
下边就用组合模式,模仿eclipse的项目展示效果,进行输出
需求
用java代码模仿eclipse项目树状的展示效果。并在控制台输出。
项目结构:
分析
首先这些东西都是资源——Resources,也就是说可以建个抽象类或者接口。
每个包是一个个的文件夹——Folder,文件夹里边又可以存文件夹和文件,里边一定有集合。
java类是一个个的文件——File,文件是叶子节点。
UML类图
代码
Resources
package 组合模式composite;
public abstract class Resources {
public String name;
public Resources(String name) {
this.name = name;
}
public abstract void add(Resources r);
public abstract void remove(Resources r);
public abstract void dispay(int depth);
}
File
package 组合模式composite;
import java.util.ArrayList;
import java.util.List;
public class File extends Resources{
List<Resources> rList = new ArrayList<>();
public File(String name) {
super(name);
}
@Override
public void add(Resources r) {
System.out.println("操作错误");
}
@Override
public void remove(Resources r) {
System.out.println("操作错误");
}
@Override
public void dispay(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print(" ");
}
System.out.println(name);
}
}
Folder
package 组合模式composite;
import java.util.ArrayList;
import java.util.List;
public class Folder extends Resources{
List<Resources> rList = new ArrayList<>();
public Folder(String name) {
super(name);
}
@Override
public void add(Resources r) {
rList.add(r);
}
@Override
public void remove(Resources r) {
rList.remove(r);
}
@Override
public void dispay(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print(" ");
}
System.out.println(name);
depth++;
for (Resources resources : rList) {
resources.dispay(depth);
}
}
}
Client
package 组合模式composite;
public class Client {
public static void main(String[] args) {
// 新建model文件夹
Folder model = new Folder("model");
// 新建dao文件夹
Folder dao = new Folder("dao");
// 新建entity文件夹
Folder entity = new Folder("entity");
// 新建UserDAO.java文件并加入到entity文件夹
entity.add(new File("UserDAO.java"));
// 将entity文件夹添加到dao
dao.add(entity);
// 新建inteface文件夹
Folder inteface = new Folder("inteface");
// 新建IUserDAO.java文件并加入到inteface文件夹
inteface.add(new File("IUserDAO.java"));
// 新建impl文件夹
Folder impl = new Folder("impl");
// 新建IUserDAOImpl.java文件并加入到impl文件夹
impl.add(new File("IUserDAOImpl.java"));
// 将impl文件夹添加到inteface
inteface.add(impl);
// 将inteface文件夹添加到dao
dao.add(inteface);
// 将dao文件夹添加到model
model.add(dao);
// 新建factory文件夹
Folder factory = new Folder("factory");
// 新建DAOFactory.java文件并加入到factory文件夹
factory.add(new File("DAOFactory.java"));
// 新建ServiceFactory.java文件并加入到factory文件夹
factory.add(new File("ServiceFactory.java"));
// 将factory文件夹添加到model
model.add(factory);
// 新建jdbc文件夹
Folder jdbc = new Folder("jdbc");
// 新建DatabaseConnection.java文件并加入到jdbc文件夹
jdbc.add(new File("DatabaseConnection.java"));
// 将jdbc文件夹添加到model
model.add(jdbc);
// 新建service文件夹
Folder service = new Folder("service");
// 新建IUserService.java文件并加入到service文件夹
service.add(new File("IUserService.java"));
// 新建jdbc文件夹
Folder impl2 = new Folder("impl");
// 新建IUserServiceImpl.java文件并加入到service文件夹
service.add(new File("IUserServiceImpl.java"));
// 新建impl2文件夹加入到service文件夹
service.add(impl2);
// 将service文件夹添加到model
model.add(service);
// 打印文件夹树状目录
model.dispay(0);
}
}
运行结果
model
dao
entity
UserDAO.java
inteface
IUserDAO.java
impl
IUserDAOImpl.java
factory
DAOFactory.java
ServiceFactory.java
jdbc
DatabaseConnection.java
service
IUserService.java
IUserServiceImpl.java
impl
对比一下
优缺点总结
优点
1、高层模块调用简单。
2、节点自由增加。
缺点
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
应用场景
部分、整体场景,如树形菜单,文件、文件夹的管理。
个人学习总结,如果有错,希望大佬指针