组合模式篇章一
思考组合模式
1 组合模式的本质
组合模式的本质: 统一叶子对象和组合对象.
组合模式通过把叶子对象当成特殊的组合对象看待,从而对叶子对象和组合对象一视同仁,
全部当成了Component对象,有机的统一了叶子对象和组合对象.
2 何时选用组合模式
①如果你想表示对象的部分-整体层次结构,可以选用组合模式
②如果你希望统一的使用组合结构中的所有对象,可以选用组合模式,这正是组合模式提供的主要功能.
相关模式(后面会写案例)
1 组合模式和装饰模式
2 组合模式和享元模式
3 组合模式和迭代器模式
4 组合模式和访问者模式
5 组合模式和职责链模式
6 组合模式和命令模式
实践案例
组合模式示例代码
1: UML类图结构

2: 组合模式角色组成
(个人理解)
抽象组件类
组合组件类
叶子组件类
3: 组合模式角色关系
抽象组件和组合组件类: 继承 + 组合(由这个组合可以组装成责任链的处理链)
抽象组件和叶子组件类: 继承
4: 案例代码
public abstract class Component {
/*
1: 定义操作
2: 还是定义操作
*/
public abstract void someOperation();
public void addChild(Component component) {
// 缺省的实现,抛出例外,因为叶子对象没有这个功能,或者子组件没有实现这个功能
throw new UnsupportedOperationException("对象不支持这个功能");
}
public void removeChild(Component component) {
throw new UnsupportedOperationException("对象不支持这个功能");
}
public Component getChildren(int index) {
throw new UnsupportedOperationException("对象不支持这个功能");
}
}
public class Composite extends Component {
/**
* 用来存储组合对象中包含的子组件对象
*/
private List<Component> childComponents = null;
@Override
public void someOperation() {
if (childComponents != null && childComponents.size() > 0) {
this.childComponents.forEach(c -> c.someOperation());
}
}
@Override
public void addChild(Component component) {
// if (this.childComponents != null) {
// this.childComponents.add(component);
// }
//延迟初始化
if (childComponents == null) {
childComponents = new ArrayList
}
childComponents.add(component);
}
@Override
public void removeChild(Component component) {
if (this.childComponents != null) {
this.childComponents.remove(component);
}
}
/**
*
* @param index
* @return
*/
@Override
public Component getChildren(int index) {
if (childComponents != null){
if(index>=0 && index<childComponents.size()){
return childComponents.get(index);
}
}
return null;
};
}
public class Leaf extends Component {
/**
*
*/
@Override
public void someOperation() {
//todo
}
}
public class Client2 {
public static void main(String[] args) {
//定义多个Composite对象
Component root = new Composite();
Component c1 = new Composite();
Component c2 = new Composite();
//定义多个叶子对象
Component leaf1 = new Leaf();
Component leaf2 = new Leaf();
Component leaf3 = new Leaf();
//组和成为树形的对象结构
root.addChild(c1);
root.addChild(c2);
root.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
//操作Component对象
Component children = root.getChildren(1);
System.out.println(children);
}
}
运行结果:
可以参考树结构.
5: 安全性和透明性
本质就是客户使用的时候是否会发生误操作的情况,如果会发生误操作,就是透明性,如果不会
发生误操作,就是安全性.
组合模式结构树代码
public abstract class Component5 {
/**
* 记录 父组件对象
*/
private Component5 parent = null;
/**
* 获取一个组件的父组件对象
* @return 一个组件的父组件对象
*/
public Component5 getParent() {
return this.parent;
}
/**
*
* @param parent
*/
public void setParent(Component5 parent) {
this.parent = parent;
}
/**
* 返回某个组件的子组件对象
* @return 某个组件的子组件对象
*/
public List<Component5> getChildren() {
throw new UnsupportedOperationException("对象不支持这个功能");
}
/-------------------以下是原有的定义----------------------/
/**
* 输出组件自身的名称
*/
public abstract void printStruct(String preStr);
/**
* 向组合对象中加入组件对象
* @param child 被加入组合对象中的组件对象
*/
public void addChild(Component5 child) {
// 缺省的实现,抛出例外,因为叶子对象没有这个功能,或者子组件没有实现这个功能
throw new UnsupportedOperationException("对象不支持这个功能");
}
/**
* 从组合对象中移出某个组件对象
* @param child 被移出的组件对象
*/
public void removeChild(Component5 child) {
// 缺省的实现,抛出例外,因为叶子对象没有这个功能,或者子组件没有实现这个功能
throw new UnsupportedOperationException("对象不支持这个功能");
}
/**
* 返回某个索引对应的组件对象
* @param index 需要获取的组件对象的索引,索引从0开始
* @return 索引对应的组件对象
*/
public Component5 getChildren(int index) {
throw new UnsupportedOperationException("对象不支持这个功能");
}
}
public class Composite5 extends Component5 {
/**
* 用来存储组合对象中包含的子组件对象
*/
private List<Component5> childComponents = null;
private String name = "";
public Composite5(String name) {
this.name = name;
}
/**
*
* @param preStr
*/
@Override
public void printStruct(String preStr) {
//先把自己输出去
System.out.println(preStr+"+"+this.name);
//如果还包含有子组件,那么就输出这些子组件对象
if(this.childComponents!=null){
//然后添加一个空格,表示向后缩进一个空格
preStr+=" ";
//输出当前对象的子对象了
for(Component5 c : childComponents){
//递归输出每个子对象
c.printStruct(preStr);
}
}
}
/**
* 新增
* @param child
*/
public void addChild(Component5 child) {
//延迟初始化
if (this.childComponents == null) {
this.childComponents = new ArrayList<>();
}
this.childComponents.add(child);
//添加对父组件的引用
child.setParent(this);
}
/**
* 其实就是将 : child 的 子组件都加到当前实例的 子组件当中
* @param child 被移出的组件对象
*/
@Override
public void removeChild(Component5 child) {
if (this.childComponents != null) {
//查找到要删除的组件在集合中的索引位置
int idx = this.childComponents.indexOf(child);
if (idx != -1) {
//先把被删除的商品类别对象的父商品类别,
// 设置成为被删除的商品类别的子类别的父商品类别
for (Component5 c : child.getChildren()) {
////删除的组件对象是本实例的一个子组件对象
c.setParent(this);
//把被删除的商品类别对象的子组件对象添加到当前实例中
this.childComponents.add(c);
}
//真的删除
this.childComponents.remove(child);
}
}
}
/**
*
* @return
*/
@Override
public List<Component5> getChildren() {
return this.childComponents;
}
}
public class Leaf5 extends Component5 {
/**
* 叶子对象的名字
*/
private String name = "";
/**
* 构造方法,传入叶子对象的名字
* @param name 叶子对象的名字
*/
public Leaf5(String name){
this.name = name;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
System.out.println(preStr+"-"+name);
}
}
public class Client5 {
public static void main(String[] args) {
//定义所有的组合对象
Component5 root = new Composite5("服装");
Component5 c1 = new Composite5("男装");
Component5 c2 = new Composite5("女装");
//定义所有的叶子对象
Component5 leaf1 = new Leaf5("衬衣");
Component5 leaf2 = new Leaf5("夹克");
Component5 leaf3 = new Leaf5("裙子");
Component5 leaf4 = new Leaf5("套装");
//按照树的结构来组合组合对象和叶子对象
root.addChild(c1);
root.addChild(c2);
c1.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);
//调用根对象的输出功能来输出整棵树
root.printStruct("");
System.out.println("---------------------------->");
//然后删除一个节点
root.removeChild(c1);
//重新输出整棵树
root.printStruct("");
}
}
运行结果:
+服装
+男装
-衬衣
-夹克
+女装
-裙子
-套装
---------------------------->
+服装
+女装
-裙子
-套装
-衬衣
-夹克
组合模式和责任链模式组合应用代码
1: 寻找两种模式的共同点,然后从结构上进行构造.
组合模式:

职责链模式:

2: 上述共同点
①都是定义了抽象类,并定义了自己的处理方法
②子类和父类都存在的关系是继承
可以参考:
https://blog.csdn.net/liuchang840302/article/details/9107399

贴出代码:
public interface Filter {
String doFilter(String str);
}
public class Filter1 implements Filter {
@Override
public String doFilter(String str) {
str += "Filter1,";
return str;
}
}
public class Filter2 implements Filter {
@Override
public String doFilter(String str) {
str += "Filter2,";
return str;
}
}
public class Filter3 implements Filter {
@Override
public String doFilter(String str) {
str += "Filter3,";
return str;
}
}
public class Filter4 implements Filter {
@Override
public String doFilter(String str) {
str += "Filter4,";
return str;
}
}
public class Filter5 implements Filter {
@Override
public String doFilter(String str) {
str += "Filter5,";
return str;
}
}
public class FilterChain implements Filter {
//这个就是组合模式的结构
List<Filter> filters = null;
//构造list
public FilterChain addFilter(Filter filter) {
//延迟初始化
if (filters == null) {
filters = new ArrayList<>();
}
filters.add(filter);
return this;
}
/**
*
* @param str
* @return
*/
@Override
public String doFilter(String str) {
if (filters == null || filters.size() == 0) {
return "处理链为空!";
}
for (Filter filter : filters) {
str = filter.doFilter(str);
}
return str;
}
}
职责链处理结果:
123,mxm,456,Filter1,Filter2,Filter5,Filter3,Filter4,
代码还需要优化!

浙公网安备 33010602011771号