遇到问题-----web前端----select默
528 2023-04-03 02:38:12
开局还是那种图,各位客官往下看...
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。(百度百科)
其实,组合模式,又称为部分整体模式,用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
关键字:一致性
,整体
,部分
比如公司的组织架构,就是树形的结构:
公司下面有部门与人,人是属于部门,部门可以拥有子部门,如果我们将上面的节点,不管是组织,还是人,统一抽象成为一个node
,那么,我们并不需要关心当前节点到底是人,还是部门,统计人数的时候或者遍历的时候,一视同仁。
还有就是Java Swing
编程中,一般也会容器的说法:Container
,我们在Container
里面可以放子的容器,也可以放具体的组件,比如Button
或者Checkbox
,其实这也是一种部分-整体的思维。
除此之外,最经典的是文件夹与文件的表示,一个文件夹(容器对象)既可以存放文件夹(容器对象),也可以存放文件(叶子对象)。如果把树的每个节点摊平,那就是List
。而树结构,则是更能直观的体现每个节点与整体的关系。
为什么需要这个模式呢?它的目的是什么?
主要是想要对外提供一致性的使用方式,即使容器对象与叶子对象之间属性差别可能非常大,我们希望抽象出相同的地方,一致的处理。
组合模式中一般有以下三种角色:
Component
):一般是接口或者抽象类,是叶子构件和容器构件对象声明接口,抽象出访问以及管理子构件的方法。Leaf
):在组合中表示叶子节点对象,叶子节点没有子节点,也就没有子构件。Composite
):容器节点可以包含子节点,子节点可以是叶子节点,也可以是容器节点。注意:关键点就是抽象构件,所有节点都统一,不再需要调用者关心叶子节点与非叶子节点的差异。
组合模式有两种不同的实现,分别是透明模式和安全模式:
两者的区别在于透明模式将组合使用的方法放到抽象类中,而安全模式则是放到具体实现类中
透明模式是把组合的方法抽象到抽象类中,不管是叶子节点,还是组合节点,都有一样的方法,这样对外处理的时候是一致的,不过实际上有些方法对叶子节点而言,是没有用的,有些累赘。
下面是代码实现:
抽象类,要求实现三个方法,增加,删除,展示:
package designpattern.composite; public abstract class Component { String name; public Component(String name) { this.name = name; } public abstract void add(Component component); public abstract void remove(Component component); public abstract void show(int depth); }
组合类:
import java.util.ArrayList; import java.util.List; public class Composite extends Component { List<Component> childs = new ArrayList<>(); public Composite(String name) { super(name); } @Override public void add(Component component) { this.childs.add(component); } @Override public void remove(Component component) { this.childs.remove(component); } @Override public void show(int depth) { for (int i = 0; i < depth; i++) { System.out.print(" "); } System.out.println(name + ": "); for (Component component : childs) { component.show(depth + 1); } } }
叶子类:
public class Leaf extends Component { public Leaf(String name) { super(name); } @Override public void add(Component component) { } @Override public void remove(Component component) { } @Override public void show(int depth) { for (int i = 0; i < depth; i++) { System.out.print(" "); } System.out.println(name); } }
测试类:
public class Test { public static void main(String[] args) { Composite folderRoot = new Composite("备忘录文件夹"); folderRoot.add(new Leaf("word 文件")); folderRoot.add(new Leaf("ppt 文件")); Composite folderLevel1 = new Composite("周报文件夹"); folderLevel1.add(new Leaf("20210101周报")); folderRoot.add(folderLevel1); Composite folderLevel2 = new Composite("笔记文件夹"); folderLevel2.add(new Leaf("jvm.ppt")); folderLevel2.add(new Leaf("redis.txt")); folderLevel1.add(folderLevel2); folderRoot.add(new Leaf("需求.txt")); Leaf leaf = new Leaf("bug单.txt"); folderRoot.add(leaf); folderRoot.remove(leaf); folderRoot.show(0); } }
运行结果如下:
备忘录文件夹: word 文件 ppt 文件 周报文件夹: 20210101周报 笔记文件夹: jvm.ppt redis.txt 需求.txt
可以看到以上是一棵树的结果,不管是叶子节点,还是组合节点,都是一样的操作。
安全模式,就是叶子节点和组合节点的特性分开,只有组合节点才有增加和删除操作,而两者都会拥有展示操作。但是如果同时对外暴露叶子节点和组合节点的话,使用起来还需要做特殊的判断。
抽象组件:
public abstract class Component { String name; public Component(String name) { this.name = name; } public abstract void show(int depth); }
组件构件:
public class Composite extends Component { List<Component> childs = new ArrayList<>(); public Composite(String name) { super(name); } public void add(Component component) { this.childs.add(component); } public void remove(Component component) { this.childs.remove(component); } @Override public void show(int depth) { for (int i = 0; i < depth; i++) { System.out.print(" "); } System.out.println(name + ": "); for (Component component : childs) { component.show(depth + 1); } } }
叶子节点:
public class Leaf extends Component { public Leaf(String name) { super(name); } @Override public void show(int depth) { for (int i = 0; i < depth; i++) { System.out.print(" "); } System.out.println(name); } }
测试类不变,测试结果也一样:
备忘录文件夹: word 文件 ppt 文件 周报文件夹: 20210101周报 笔记文件夹: jvm.ppt redis.txt 需求.txt
安全模式中,叶子节点没有多余的方法,没有空的方法,外面调用的时候,不会调用到空方法。但是需要对节点进行判断,才能知道哪一个方法能调,哪一个方法不能调。
组合模式的优点:
缺点:
使用场景:
希望忽略每个部分的差异,客户端一致使用
需要表现为树形结构,以表示“整体-部分”的结构层次。
以一句网友的话结尾:
“张无忌学太极拳,忘记了所有招式,打倒了"玄冥二老",所谓"心中无招"。设计模式可谓招数,如果先学通了各种模式,又忘掉了所有模式而随心所欲,可谓OO之最高境界。”
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,个人网站:http://aphysia.cn,技术之路不在一时,山高水长,纵使缓慢,驰而不息。
剑指Offer全部题解PDF
开源编程笔记
设计模式系列:
__EOF__
本文作者:秦怀杂货店