前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的组合模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
组合模式
组合模式是一种结构型设计模式,它允许你将对象组合成树状结构,并且能像使用单个对象一样使用组合对象和单个对象。
在组合模式中,有两种类型的对象:单个对象(Leaf)和组合对象(Composite)。组合对象可以包含其他组合对象或单个对象,从而形成树状结构。组合对象中通常会定义添加、删除、获取子对象等操作,而单个对象没有这些操作。
举一个例子:需要展示某个组织机构的层级结构,如公司的部门、子部门和员工等等。在这种情况下,组织机构可以被视为一个组合对象,而部门、子部门和员工可以被视为单个对象。
下面是一个简单的 Java 代码示例,展示了如何使用组合模式来表示组织机构的层级结构:
- 抽象组件
interface Component {
void show();
}
- 叶子节点
class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
public void show() {
System.out.println(name);
}
}
- 组合节点
class Composite implements Component {
private String name;
private List<Component> children = new ArrayList<>();
public Composite(String name) {
this.name = name;
}
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
public void show() {
System.out.println(name);
for (Component component : children) {
component.show();
}
}
}
怎么使用呢?
public class CompositeTest {
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
在上面的示例中,我们创建了抽象组件 Component 接口来定义组合对象和单个对象的通用方法。叶子节点 Leaf 表示单个对象,而组合节点 Composite 表示组合对象。我们将组合节点中的子节点存储在一个 List 中,从而实现了层级结构。在 Composite 中,我们实现了添加、删除和展示子节点的操作,而在 Leaf 中,我们只实现了展示自身的操作
最佳实践
假设在电商平台上有一些商品,这些商品可以被分为两类:单品和组合商品。单品是指仅由一个商品组成的商品,而组合商品是指由多个商品组合而成的商品。这里使用组合模式来实现这种商品的分类。
首先定义一个商品接口,包含获取商品名称、获取商品价格等方法:
public interface Product {
String getName();
double getPrice();
}
然后定义一个单品类,实现商品接口:
public 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;
}
}
接下来定义一个组合商品类,它包含多个子商品,实现商品接口:
public 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 CompositeTest {
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
通过组合模式,可以方便地创建和管理多个商品的组合,而不需要考虑它们是单品还是组合商品,简化了代码的实现和维护。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲装饰器模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看