1、组合模式基本介绍
组合模式
是一种结构型设计模式,它允许你将对象组合成树状结构
,并且能像使用单个对象一样使用组合对象和单个对象。
在组合模式
中,有两种类型的对象:单个对象(Leaf)
和组合对象(Composite)
。
组合对象可以包含其他组合对象或单个对象,从而形成树状结构
。
组合对象中通常会定义添加、删除、获取
子对象等操作,而单个对象没有这些操作。
2、场景推导
业务场景:现在需要展示某个组织机构的层级结构,如公司的部门、子部门和员工等等。
在这种情况下,组织机构可以被视为一个组合对象,而部门、子部门和员工可以被视为单个对象。
-
抽象组件
//抽象组件 interface Component { void show(); }
-
叶子节点
//叶子节点 class Leaf implements Component { private String name; public Leaf(String name) { this.name = name; } @Override public void show() { System.out.println(name); } }
-
组合节点
//组合节点 class Composite implements Component { private String name; public Composite(String name) { this.name = name; } //集合 private List<Component> children = new ArrayList<>(); //操作集合的方法 public void add(Component component) { children.add(component); } public void remove(Component component) { children.remove(component); } @Override public void show() { System.out.println(name); for (Component component : children) { component.show(); } } }
-
客户端
public class AppTest { public static void main(String[] args) throws Exception { // 构建组织机构的层级结构 Composite root = new Composite("公司"); Composite department1 = new Composite("部门1"); Composite department2 = new Composite("部门2"); Composite subDepartment1 = new Composite("子部门1"); Leaf employee1 = new Leaf("员工1"); Leaf employee2 = new Leaf("员工2"); Leaf employee3 = new Leaf("员工3"); root.add(department1); root.add(department2); department1.add(subDepartment1); subDepartment1.add(employee1); subDepartment1.add(employee2); department2.add(employee3); // 展示组织机构的层级结构 root.show(); } }
-
运行结果
公司 部门1 子部门1 员工1 员工2 部门2 员工3 Process finished with exit code 0
在上面的栗子中,我们创建了抽象组件 Component 接口来定义组合对象和单个对象的通用方法。
- 叶子节点 Leaf 表示单个对象,而组合节点 Composite 表示组合对象。
- 我们将组合节点中的子节点
存储在一个 List
中,从而实现了层级结构。 - 在 Composite 中,我们实现了添加、删除和展示子节点的操作,而在 Leaf 中,我们只实现了展示自身的操作
UML图
3、最佳实践
业务需求:
假设在电商平台上有一些商品,这些商品可以被分为两类:单品和组合商品。
单品是指仅由一个商品组成的商品,而组合商品是指由多个商品组合而成的商品。
这里使用组合模式来实现这种商品的分类。
-
首先定义一个商品接口,包含获取商品名称、获取商品价格等方法:
interface Product { String getName(); double getPrice(); }
-
然后定义一个单品类,实现商品接口:
class SingleProduct implements Product { private String name; private double price; public SingleProduct(String name, double price) { this.name = name; this.price = price; } @Override public String getName() { return name; } @Override public double getPrice() { return price; } }
-
接下来定义一个组合商品类,它包含多个子商品,实现商品接口:
class CompositeProduct implements Product { private String name; private List<Product> products = new ArrayList<>(); public CompositeProduct(String name) { this.name = name; } public void addProduct(Product product) { products.add(product); } public void removeProduct(Product product) { products.remove(product); } @Override public String getName() { return name; } @Override public double getPrice() { double totalPrice = 0; for (Product product : products) { totalPrice += product.getPrice(); } return totalPrice; } }
-
客户端
public class AppTest2 { public static void main(String[] args) throws Exception { CompositeProduct root = new CompositeProduct("苹果全家桶"); Product product1 = new SingleProduct("手机", 188.00); Product product2 = new SingleProduct("平板", 288.00); Product product3 = new SingleProduct("笔记本", 168.00); root.addProduct(product1); root.addProduct(product2); root.addProduct(product3); System.out.println(root.getName()); System.out.println(root.getPrice()); }
-
运行结果
苹果全家桶 644.0 Process finished with exit code 0
通过组合模式
,可以方便地创建和管理多个商品的组合,而不需要考虑它们是单品还是组合商品,简化了代码的实现和维护。