设计模式11-- 搞定组合模式

Posted 秦怀杂货店

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式11-- 搞定组合模式相关的知识,希望对你有一定的参考价值。

设计模式【11】--

开局还是那种图,各位客官往下看...

组合模式是什么?

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。(百度百科)

其实,组合模式,又称为部分整体模式,用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。 关键字:一致性,整体部分

比如公司的组织架构,就是树形的结构:

设计模式【11】--

公司下面有部门与人,人是属于部门,部门可以拥有子部门,如果我们将上面的节点,不管是组织,还是人,统一抽象成为一个node,那么,我们并不需要关心当前节点到底是人,还是部门,统计人数的时候或者遍历的时候,一视同仁。 还有就是Java Swing编程中,一般也会容器的说法:Container,我们在Container里面可以放子的容器,也可以放具体的组件,比如Button或者Checkbox,其实这也是一种部分-整体的思维。 除此之外,最经典的是文件夹与文件的表示,一个文件夹(容器对象)既可以存放文件夹(容器对象),也可以存放文件(叶子对象)。如果把树的每个节点摊平,那就是List。而树结构,则是更能直观的体现每个节点与整体的关系。

为什么需要这个模式呢?它的目的是什么?

主要是想要对外提供一致性的使用方式,即使容器对象与叶子对象之间属性差别可能非常大,我们希望抽象出相同的地方,一致的处理。

组合模式的角色

组合模式中一般有以下三种角色:

  • 抽象构件(Component):一般是接口或者抽象类,是叶子构件和容器构件对象声明接口,抽象出访问以及管理子构件的方法。
  • 叶子节点(Leaf):在组合中表示叶子节点对象,叶子节点没有子节点,也就没有子构件。
  • 容器构件(Composite):容器节点可以包含子节点,子节点可以是叶子节点,也可以是容器节点。

注意:关键点就是抽象构件,所有节点都统一,不再需要调用者关心叶子节点与非叶子节点的差异。

组合模式的两种实现

组合模式有两种不同的实现,分别是透明模式安全模式

两者的区别在于透明模式将组合使用的方法放到抽象类中,而安全模式则是放到具体实现类中


透明模式

透明模式是把组合的方法抽象到抽象类中,不管是叶子节点,还是组合节点,都有一样的方法,这样对外处理的时候是一致的,不过实际上有些方法对叶子节点而言,是没有用的,有些累赘。

设计模式【11】--

下面是代码实现: 抽象类,要求实现三个方法,增加,删除,展示:

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(undefined undefined);

System.out.println(name + undefined: undefined);
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(undefined undefined);

System.out.println(name);

测试类:

public class Test 
public static void main(String[] args)
Composite folderRoot = new Composite(undefined备忘录文件夹undefined);
folderRoot.add(new Leaf(undefinedword 文件undefined));
folderRoot.add(new Leaf(undefinedppt 文件undefined));

Composite folderLevel1 = new Composite(undefined周报文件夹undefined);
folderLevel1.add(new Leaf(undefined20210101周报undefined));
folderRoot.add(folderLevel1);


Composite folderLevel2 = new Composite(undefined笔记文件夹undefined);
folderLevel2.add(new Leaf(undefinedjvm.pptundefined));
folderLevel2.add(new Leaf(undefinedredis.txtundefined));
folderLevel1.add(folderLevel2);


folderRoot.add(new Leaf(undefined需求.txtundefined));


Leaf leaf = new Leaf(undefinedbug单.txtundefined);
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 设计模式 结构型模式 -- 组合模式

组合模式 - 设计模式 - PHP版

[工作中的设计模式]组合模式compnent

设计模式8之c+组合模式的使用和优化

设计模式的征途—9.组合(Composite)模式

设计模式之组合模式