【Java设计模式】结构型设计模式-组合模式(十二)

组合模式

  • 组合模式的也叫做整体-部分模式,它是一种将对象组合成树状的层次结构的模式,用来表示"整体-部分"的关系,使用户对单个对象和组合对象具有一致的访问性。

进一步阐述:

  • 组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点。其实就是我们常说的"树型结构"。

组合模式包含四种角色:

  • Component(抽象构件角色):它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)
  • Leaf(树叶构件角色):是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。
  • Composite(树枝构件角色 / 中间构件角色):是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

案例:实现当用户在商店购物后,显示其所选商品信息,并计算所选商品总价的功能。

UML类图:

客户端Client类:

java 复制代码
/**
 * 使用组合模式的客户端
 */
public class Client {
​
    public static void main(String[] args) {
        Bags bigBag = new Bags("大商品袋");
        Bags mediumBag = new Bags("中商品袋");
        Bags smallBag = new Bags("小商品袋");
​
        Goods sneakers = new Goods("运动鞋", 1, 1198);
        Goods snacks = new Goods("零食", 5, 5);
        Goods vegetables = new Goods("蔬菜", 5, 1.5);
​
        //中商品袋中放入运动鞋
        mediumBag.add(sneakers);
        //小商品袋中放入零食和蔬菜
        smallBag.add(snacks);
        smallBag.add(vegetables);
        //把中商品袋和小商品袋一起放入大商品袋组合起来
        bigBag.add(mediumBag);
        bigBag.add(smallBag);
        //打印所有的商品信息
        bigBag.show();
        double total = bigBag.calculation();
        System.out.println("要支付的总价是:" + total);
    }
}

商店物品Articles接口:

java 复制代码
/**
 * 商店物品(抽象构件)
 */
public interface Articles {
​
    /**
     * 计算方法
     */
    double calculation();
​
    /**
     * 展示信息
     */
    void show();
}

袋子Bags类:

java 复制代码
/**
 * 袋子类(树枝构件)
 */
public class Bags implements Articles {
​
    /**
     * 袋子名称
     */
    private String name;
​
    /**
     * 持有商品的集合
     */
    private List<Articles> bags = new ArrayList<>();
​
    public Bags(String name) {
        this.name = name;
    }
​
    /**
     * 添加商品
     */
    public void add(Articles articles) {
        bags.add(articles);
    }
​
    /**
     * 删除商品
     */
    public void remove(Articles articles) {
        bags.remove(articles);
    }
​
    /**
     * 获取某一个商品
     */
    public Articles getChild(int i) {
        return bags.get(i);
    }
​
    /**
     * 计算所有价格
     */
    public double calculation() {
        BigDecimal total = new BigDecimal("0");
        for (Articles bag : bags) {
            total = total.add(BigDecimal.valueOf(bag.calculation()));
        }
        return total.doubleValue();
    }
​
    /**
     * 打印所有商品信息
     */
    public void show() {
        for (Articles bag : bags) {
            bag.show();
        }
    }
}

商品Goods类:

java 复制代码
/**
 * 商品类(树叶构件)
 */
public class Goods implements Articles {
​
    /**
     * 商品名称
     */
    private String name;
​
    /**
     * 商品数量
     */
    private int quantity;
​
    /**
     * 商品单价
     */
    private double unitPrice;
​
    public Goods(String name, int quantity, double unitPrice) {
        this.name = name;
        this.quantity = quantity;
        this.unitPrice = unitPrice;
    }
​
    @Override
    public double calculation() {
        return BigDecimal.valueOf(unitPrice)
                .multiply(BigDecimal.valueOf(quantity)).doubleValue();
    }
​
    @Override
    public void show() {
        System.out.println(name + "(数量:" + quantity + ",单价:" + unitPrice + "元)");
    }
}

总结:

  • 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码。
  • 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足"开闭原则"。
  • 设计较复杂,客户端需要花更多时间理清类之间的层次关系。不容易限制容器中的构件。不容易用继承的方法来增加构件的新功能。

典型运用场景举例:

  • 在需要表示一个对象整体与部分的层次结构的场合。例如:文件目录显示,多及目录呈现等。
  • 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合,比如树形结构中的二叉树。
相关推荐
丁总学Java12 分钟前
--spring.profiles.active=prod
java·spring
上等猿19 分钟前
集合stream
java
java1234_小锋23 分钟前
MyBatis如何处理延迟加载?
java·开发语言
菠萝咕噜肉i24 分钟前
MyBatis是什么?为什么有全自动ORM框架还是MyBatis比较受欢迎?
java·mybatis·框架·半自动
海绵波波10733 分钟前
flask后端开发(1):第一个Flask项目
后端·python·flask
林的快手38 分钟前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
zh路西法1 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(二):从FSM开始的2D游戏角色操控底层源码编写
c++·游戏·unity·设计模式·状态模式
向阳12181 小时前
mybatis 缓存
java·缓存·mybatis
上等猿1 小时前
函数式编程&Lambda表达式
java
夏旭泽1 小时前
设计模式-备忘录模式
设计模式·备忘录模式