首页 - 新闻 - 小龙打败面试官系列:组合模式

小龙打败面试官系列:组合模式

2023-10-10 09:15

文章列表

  • 1。组合模式介绍


    • 1。什么是组合模式

    • 2。组合模式使用场景

  • 2.通过业务场景描述组合模型


    • 1。提出使用场景

    • 2。业务分析

  • 3。组合模式分类及实现


    • (1)创建组件

    • (2) 创建合成

    • (3)创建叶子

    • (4)创建测试用例和测试结果

    • (1) 创建组件

    • (2) 创建合成

    • (3)创建叶子

    • (4)创建测试用例和测试结果

    • 1。实现透明组合模式


    • 2。实现安全组合模式


  • 4。汇总组合模式


    • 1。组合方式的构成

    • 2。组合方式结构图

    • 3。组合模式的优缺点

    • 4。 JDK中组合模式的使用


1。组合模式介绍

1。什么是组合模式

复合模式是结构设计模式的一种,也称为部分整体模式。该模式是为了解决显示一组相似对象的层次结构的问题,通过将对象组合成树形结构来表示部分-整体的层侧结构。复合模式支持单个和复合对象的一致使用。

2。组合模式使用场景

组合模式通常应用于两种场景:

  1. 当您想要表示对象的一部分时 - 整体层次结构(树结构)

  2. 你希望用户忽略整体对象和单个对象之间的差异,用户将统一使用复合结构中的所有对象

2.通过业务场景描述组合模型

1。提出使用场景

举个简单的例子,我们计算机的文件系统其实是一个非常典型的树形结构。例如,当我们想要保存一个文件时,操作系统会让我们选择一个保存路径。那么我们来简单分析一下这条路径,看看它是否有明显的层级关系。

首先,D:代表我们要存储的目标盘,Users动画就是我们要保存的路径。该路径由多个文件夹组成,每一级文件夹可能不止一个下级文件夹,例如我们打开动画文件夹可以看到:

假设我们电脑中D盘的文件系统结构如下,那么我想创建一个简单的模型来展示这个系统结构。我应该怎么办?

2。业务分析

首先我们来分析一下这个文件系统的一个业务属性。首先,无论是D盘还是下级文件夹目录,都具有维护文件的功能和属性。简单来说,就是可以对文件进行添加、删除、修改、查看相关操作。其次,它们都有一定的固有属性,比如名称、大小等,那么我们是否可以将这些共享的属性和行为分离出来,以达到功能复用和方便扩展维护的目的呢?当然有可能。这里我们提到的是提取所有公共部分,也就是组合模式抽象根节点(组件)的第一个组件角色。组件是复合模式下的对象声明接口。主要负责定义所有类所拥有的共同行为和属性,用于方便业务方访问和管理子类。有了抽象根节点,接下来我们需要分析的是各级文件夹的功能。它们主要用于存储文件。如果我们把整个文件系统比作一棵树,那么每一级文件夹就是一棵树。树枝,每层文件夹下保存的文件是树的叶子。那么分支在复合系统中的作用就是树节点(复合)。 Composite主要用来存储子节点。整个文件系统最后一级的各个格式的文件本身不具备存储节点的能力,因此它们就像一棵树的叶子,扮演着叶节点(leaf)的角色。 leaf 下面没有其他分支,是组合模式系统层次结构的最小单位。然后我们将系统结构图按照我们分析的模式进行转换,可以看到:

3。组合模式的分类与实现

合成模式一般有两种实现:透明模式和安全模式。两种模式的主要区别在于透明模式会将组合的所有共同行为放到一个统一的组件中,不同级别的节点具有一致的行为。这样做的好处是客户端可以统一使用,不用区分是哪一级节点。然而,缺点也很明显。叶节点将继承相同的行为。无用的行为。所以,安全模式就是为了解决这个问题。在安全模式下,组件只会抽象出基本的行为,分支节点和叶子节点本身的方法需要自己实现。

1。实现透明组合模式

废话不多说,我们使用透明组合方式来实现文件系统级别的遍历功能;

(1) 创建组件

公共抽象文件组件  {

受保护 字符串名称;

// 限制文件创建有自己的名称


public FileComponent() 字符串名称) {
超级();
这个. 姓名=姓名;
}

// 允许获取名称
public String getName (){
回归? public void setName字符串名称{
这个. name = name;
}

//添加下级节点 公共 添加(FileComponent fileComponent) {
不支持的操作异常 ("暂不支持此方法");
}

//查询
公共抽象空白打印();

}


(2) 创建合成

公共  文件复合 扩展  FileComponent {
私有列表<文件组件>文件复合= ArrayList<文件组件>( );

public 文件复合(字符串名称) ) {
超级(名称);
}

@Override 公共添加(FileComponent fileComponent){
FileComposite. 添加(文件组件);
}

@Override
公共 void 打印() {
系统.out.println(getName( ));
for (FileComponent fileComponent : FileComposite) {
系统.输出.打印(" -");
文件组件.打印();
}
}

}


(3)创建叶子

公共  FileLeaf 扩展  文件组件 {

公共 FileLeaf字符串名称 {
超级(名字);

}

@Override
公共 void 打印() {
系统.输出.println("-"+ getName());
系统.输出.println( “-------------”);

}

}


(4)创建测试用例及测试结果

公共  测试 {

公共 静态 main(String[]args) {
文件组件 文件合成 = FileComposite("D:");
FileComponent 用户 = 文件合成("用户");
文件组件游戏= 文件合成“游戏” );
文件合成.添加(用户) ;
文件合成.添加(游戏);
FileComponent gif = 文件合成("动图");
用户.添加(gif);
文件组件 fileLeaf = FileLeaf("组合模式.gif");
gif添加(fileLeaf);
文件合成.打印();
}
}


测试结果:

2。实现安全组合模式

(1) 创建组件

公共抽象文件组件  {

受保护 字符串名称;

public 文件组件字符串名称 {
超级();
这个.姓名=姓名;
}

公共字符串 getName () {
返回姓名 ;
}

公共 setName(字符串名称) {
这个.姓名=姓名;
}


公共抽象空白打印();
}


(2) 创建合成

公共  文件复合 扩展  FileComponent {

私有列表<文件组件>文件复合= ArrayList<文件组件>( );

public 文件复合(字符串名称) ) {
超级(name);
// TODO 自动生成的构造函数存根
}

@覆盖
公共 void 打印 {
系统.输出.println (getName());
对于 (FileComponent 文件组件 : FileComposite) {
系统.out. 打印("-");
文件组件.打印();
} }

公共 void add(FileComponent fileComponent) {
FileComposite.add(fileComponent);
}


}


(3)创建叶子

公共  FileLeaf 扩展  文件组件 {

公共 FileLeaf字符串名称 {
超级(名字);
}

@Override
公共 void 打印() {
系统.输出.println("-"+ getName());
系统.输出.println( “-------------”);
}

}

(4)创建测试用例及测试结果

公共  测试 {

公共 静态 main(String[]args) {
文件合成 文件合成 = FileComposite("D:");
FileComposite 用户 = 文件合成("用户");
文件合成游戏= 文件合成“游戏” );
文件合成.添加(用户) ;
文件合成.添加(游戏);
文件合成gif= 文件合成("动图");
用户.添加(gif);
文件组件 fileLeaf = FileLeaf("组合模式.gif");
gif添加(fileLeaf);
文件合成.打印();
}
}


测试结果:

4。汇总组合模式

1。组合模式的构成

组合模式分为三个字符:

  1. 抽象根节点(组件):负责定义系统各个层面的公共属性和方法,也可以预先实现一些默认的行为和属性。

  2. 树节点(复合):负责存储子节点,具有系统共有的属性和行为。

  3. 叶节点(leaf):叶节点,其下没有分支,是系统层次结构的最小单位。

2。组合方式结构图

如图:

3。组合模式的优缺点

优点:

  1. 组合模式抽象了系统的公共属性,隐藏了对象之间的差异,使得业务系统在使用时可以忽略差异,用一致的行为来控制不同层次。

  2. 可以轻松添加下级节点,无需侵入现有类库,且符合开闭原则。

缺点:

  1. 如果树结构太大,系统的深度遍历可能会导致运行时间过长。

  2. 组合模式违反了依赖倒置原则

4。 JDK中组合模式的使用

JDK中Map类的实现指的是组合模式。有兴趣的同学可以自行查看源码和资料,这里不再赘述。

好了,今天的内容就到此结束。如果还有疑问,可以私信我或者在评论区留言,我会尽快为您解答。觉得有所收获的朋友们,请记得点三下,关注博主,不要迷路,拒绝做免费的妓女~