常用设计模式系列(十三)—组合模式
第一节
前言
hello大家好,今年已经过去了一半,年初立下的flag,不知道实现了没有,你的flag改了多少次?无论自己的愿望是否完成,我们都应该怀揣着追逐梦想之心,去尝试突破上一年的自我。我去年的flag虽然也没有实现,但是自己努力去做了,结果其实并不重要,更不要成为自己内心阻挠自己努力的绊脚石,加油,年轻人!
今天学习对象结构型设计模式的最后一章:组合模式,组合模式可以理解为整体+部分,一个整体有多个部分组成,例如一个树由多个主干组成,每个主干又有多个树杈,每个树杈又有多个树叶。
第二节
组合模式
组合(Composite
Pattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。组合模式一般是用来描述整体与部分的关系,我们可以把它应用到数据结构的树形结构当中,顶层的节点就是根节点,根节点下面可以包含多个树枝节点和多个叶子节点,树枝节点下面又可以包含树枝节点和叶子节点,类似于我们学习数据结构中的树形结构。在组合模式中,整个树形结构中的对象都属于同一种类型,带来的好处就是用户不需要辨别是树枝节点还是叶子节点,可以直接进行操作,给用户的使用带来极大的便利。
前两天圣诞节,小张同学为了庆祝过节,跑到了大超市买了很多的菜与肉类,从超市出来,小张同学买了许多的物品,跟超市的售货员要了很大的带子,这个大袋子里装了用中型号袋子装的各种蔬菜、塑料包装的肉卷,小袋子装的散装丸子和小袋子装的火锅底料,中型的带子里又装了许多小袋子,每个小袋子都是一种蔬菜,而小袋子装的盒子里面有三个更小的盒子,每个盒子分别是鸡肉卷、羊肉卷、肥牛卷。这种大袋子套中袋子和物品,中袋子又套小袋子和物品的场景,无论是大袋子还是小袋子还是蔬菜,都属于物品,这种嵌套组合,就是组合模式。
第三节
代码实现
1.编写抽象构件
package com.yang.composite;
/**
* @ClassName Articles
* @Description 抽象构件-物品
* @Author IT小白架构师之路
* @Date 2020/12/29
* @Version 1.0
**/
public interface Articles {
//计算价格
public float calculation();
//展示内容方法
public void show();
}
2.编写树枝角色
package com.yang.composite;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName Bags
* @Description 树枝构件:袋子
* @Author IT小白架构师之路
* @Date 2020/12/29
* @Version 1.0
**/
public class Bags implements Articles {
private String name; //名字
private List<Articles> bags = new ArrayList<Articles>();
public Bags(String name) {
this.name = name;
}
public void add(Articles c) {
bags.add(c);
}
public void remove(Articles c) {
bags.remove(c);
}
public Articles getChild(int i) {
return bags.get(i);
}
public float calculation() {
float s = 0;
for (Object obj : bags) {
s += ((Articles) obj).calculation();
}
return s;
}
public void show() {
for (Object obj : bags) {
((Articles) obj).show();
}
}
}
3.编写树叶角色
package com.yang.composite;
/**
* @ClassName Goods
* @Description 树叶构件:商品
* @Author IT小白架构师之路
* @Date 2020/12/29 16:53
* @Version 1.0
**/
public class Goods implements Articles {
private String name; //名字
private int quantity; //数量
private float unitPrice; //单价
//构造方法
public Goods(String name, int quantity, float unitPrice) {
this.name = name;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
public float calculation() {
return quantity * unitPrice;
}
public void show() {
System.out.println(name + "(数量:" + quantity + ",单价:" + unitPrice + "元)");
}
}
4.编写测试类
package com.yang.composite;
/**
* @ClassName Client
* @Description 客户端测试
* @Author IT小白架构师之路
* @Date 2020/12/29
* @Version 1.0
**/
public class Client {
public static void main(String[] args) {
float s = 0;
Bags BigBag, mediumBag, smallRedBag, smallWhiteBag;
Goods sp;
BigBag = new Bags("大袋子");
mediumBag = new Bags("中袋子");
smallRedBag = new Bags("红色小袋子");
smallWhiteBag = new Bags("白色小袋子");
sp = new Goods("菠菜", 2, 7.9f);
smallRedBag.add(sp);
sp = new Goods("火锅底料", 1, 9.9f);
smallRedBag.add(sp);
sp = new Goods("羊肉", 2, 38);
smallWhiteBag.add(sp);
sp = new Goods("红酒", 3, 180);
smallWhiteBag.add(sp);
sp = new Goods("鸭血", 1, 10);
mediumBag.add(sp);
mediumBag.add(smallRedBag);
sp = new Goods("土豆", 1, 3);
BigBag.add(sp);
BigBag.add(smallWhiteBag);
BigBag.add(mediumBag);
System.out.println("您选购的商品有:");
BigBag.show();
s = BigBag.calculation();
System.out.println("要支付的总价是:" + s + "元");
}
}
5.运行结果如下
您选购的商品有:土豆(数量:1,单价:3.0元)
羊肉(数量:2,单价:38.0元)
红酒(数量:3,单价:180.0元)
鸭血(数量:1,单价:10.0元)
菠菜(数量:2,单价:7.9元)
火锅底料(数量:1,单价:9.9元)
要支付的总价是:654.7元
第四节
优缺点分析与适用场景
优点
1.组合模式使客户端代码可以统一且通用的处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,简化了调用者的逻辑
2.在组合体内部增加对象变得很轻松,不需要修改源代码来增加新的对象.
缺点:
1.设计的过程中,要考虑满足类之前的通用抽象性,否则无法使用组合模式
2.如果限制具体构建,则很难限制.
3.不容易使用继承的方法来扩展新功能,只能使用别的方式
适用场景
1.当系统中一些对象能够按照一致的方式去处理,例如无限极菜单\无限极权限,需要对象与整体同时使用。
2.需要隐藏组合对象与单个对象不同时,不同的单个对象的特殊方法,也不能被访问到的场景。
3.只需要客户端对抽象构建编程,不需要考虑内部实现的场景。
扫描二维码
关注我吧
IT小白架构师之路