Java23种设计模式——12.结构型模式之组合模式

Java中除去有设计原则之外,还有23中设计模式。

这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,而这些设计模式可以解决一些特定的问题。

并且在这些模式中,可以说是将语言的使用体现的淋漓尽致。

那我们今天要学习  结构型模式  中的  组合模式  !

组合模式

首先我们先看一下什么叫组合模式,直接百度百科


额、可能不是很明白,但是我们说一个东西大家就知道了,比如说菜单

菜单就是将一个一个的部分构成一个整体的菜单。

组合模式的定义与特点

组合(Composite)模式的定义:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。

组合模式的主要优点有:

1. 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;

2. 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;


其主要缺点是:

1. 设计较复杂,客户端需要花更多时间理清类之间的层次关系;

2. 不容易限制容器中的构件;

3. 不容易用继承的方法来增加构件的新功能;

组合模式的结构与实现

这个设计模式中主要是有三个角色

1. 抽象构件角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。

2. 树叶结构角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。

3. 树枝结构角色:是组合中的分支节点对象,它有子节点。

而且,除去这个角色,组合模式还有两种方式去实现,一个是透明式,一个是安全式

透明式:在该方式中,由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。但其缺点是:树叶构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。

安全式:在该方式中,将管理子构件的方法移到树枝构件中,抽象构件和树叶构件没有对子对象的管理方法,这样就避免了上一种方式的安全性问题,但由于叶子和分支有不同的接口,客户端在调用时要知道树叶对象和树枝对象的存在,所以失去了透明性。

然后我们来使用一下这个东西,感受感受,这里我们使用透明式,安全式的话不同的点在于所有的接口实现方法不会定义在抽象组件里,而是在具体的树枝结构中

场景:好比说我们收拾家,家里现在有一个大碗,一个小碗,一双筷子,一个盆子,一个刷碗布,还有一大堆的纸箱子。

我们现在将大碗、小碗放在一个小的纸箱子中,再把筷子、盆子、刷碗布放在另外的一个大纸箱中,最后输出当前的结构,我们来看看用代码怎么写

第一步:

我们先弄一个公共的抽象构件,我们起一个名字,叫 Article 物品,里面我们需要定义一个接口方法即可,就是查看里面的东西

第二步:

接下来呢,我们先定义这个家里的这些碗、筷子啥的东西,这个是树叶结构,这个东西需要实现刚刚上面的接口,并且我们还需要定义这个物品的名字,我们来看一下怎么去弄

第三步:

第三步我们就需要定义这个树枝了,这个树枝其实就是纸箱子,同样需要实现这个 Article 物品的接口

当然啊,除去这些还不够,我们还需要继续写。这个纸箱子呢,也不是就一个,而且也不会是一模一样的,所以呢,我们需要有一个名字去做区分,比如说 A箱子,B箱子这样

我们的箱子里需要存取东西,所以我们还需要写两个接口,一个是 add 添加,一个是 remove 取,而这连个东西需要定义在物品的接口中,所以我们需要先改一下接口

可以看到,其他的实现类都报错了,这里我们再去修改一下

Kitchen 我们不需要动,只需要实现即可,方法体里面空着即可,我们主要是想让 Carton 做实现,我们做添加或者移除,我们可以通过 ArrayList 去做实现,所以我们需要定义一个私有的数组

这里我们再去把 selectArticle也实现一下,主要是遍历纸箱子里面的东西。

最后再加一个 name 的 get set 方法即可

测试:

接着我们创建一个测试类 Test 然后我们来实现一下

测试的话我们需要将商品都先弄好,家里的碗啊、筷子之类的,还有两个纸箱子,大纸箱子和小纸箱子

(PS:这里有一个错误,我把纸箱子的构造弄成了私有,大家自己修改一下,弄成 public ,不然没有办法实例化)

写好之后,我们将大碗、小碗 add 到小纸箱中

然后将其他的东西放在大纸箱里面

最后我们可以看一下这两个纸箱子里面有啥

执行一下

是OK的,没有问题的,这个就是透明式的组合模式,当然,安全式的,我们其实就不将一些没有用的方法定义在抽象构件里面了,那里需要用到那里定义。这个大家可以自己尝试的做一下

OK,就到这里,大家好好看一下。多多练习。有问题可以联系我QQ:2100363119

欢迎大家访问我的个人网站:lemon1234.com 感谢大家留言

猜你喜欢

转载自blog.csdn.net/weixin_45908370/article/details/109319462