一、角色
抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)
树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。
树枝构件(Composite)角色 / 中间构件:是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。
二、编程实战
2.1demo
为了偷懒就写在一个文件上了
/**
* @describe: 场景描述:超时购物收银
* 购买了两双鞋,1块面包,拿了一个购物袋
* @author:zqm
*/
public class CompositePatternDemo2 {
public static void main(String[] args) {
//树叶构件(Leaf)角色1
Goods shoes = new Goods(10, 2, "拖鞋");
//树叶构件(Leaf)角色2
Goods bread = new Goods(5, 1, "面包");
//树叶构件(Leaf)角色3
Goods bag = new Goods(1, 1, "袋子");
//树枝构件(Composite)角色 / 中间构件
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.addGoods(shoes);
shoppingCart.addGoods(bread);
shoppingCart.addGoods(bag);
shoppingCart.show();
System.out.println("合计" + shoppingCart.calculation());
}
/**
* 抽象构件(Component)角色
* 接口功能:计算价格和展示明细
*/
interface Articles {
//计算
float calculation();
void show();
}
/**
* 产品抽象类,包含属性单价,数量以及名称
*/
static class Goods implements Articles {
private float price;
private int num;
private String name;
public Goods() {
}
public Goods(float price, int num, String name) {
this.price = price;
this.num = num;
this.name = name;
}
@Override
public float calculation() {
return num * price;
}
@Override
public void show() {
System.out.println(name + "( 数量是:" + num + "单价是:" + price + ")");
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 购物车抽象类 个功能:添加物品/移除物品
*/
static class ShoppingCart implements Articles {
private List<Articles> list = new ArrayList<>();
public void addGoods(Articles articles) {
list.add(articles);
}
public void removeGoods(Articles articles) {
list.remove(articles);
}
public List<Articles> getList() {
return list;
}
public void setList(List<Articles> list) {
this.list = list;
}
@Override
public float calculation() {
float totalPrice = 0;
for (Articles articles : list) {
totalPrice += articles.calculation();
}
return totalPrice;
}
@Override
public void show() {
for (Articles articles : list) {
articles.show();
}
}
}
}
2.2结果验证
三、组合模式的应用场景
1. 在需要表示一个对象整体与部分的层次结构的场合。
2. 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。