前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的装饰器模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给一个对象添加额外的职责,而不需要修改原始类的代码。这种模式是作为替代继承方式的一种实现。
在装饰器模式中,有一个基本的接口或抽象类,定义了被装饰对象和装饰器对象之间的公共方法。装饰器对象和被装饰对象都实现了该接口或抽象类,并且装饰器对象还有一个成员变量指向被装饰对象,从而形成了一个装饰器对象链。
下面是一个简单的示例,展示了如何使用装饰器模式来扩展基础功能:
// 定义一个基本的组件接口 interface Component { void operation(); } // 定义一个具体的组件类 class ConcreteComponent implements Component { public void operation() { System.out.println("ConcreteComponent.operation()"); } } // 定义一个装饰器基类,维护一个指向被装饰对象的引用 class Decorator implements Component { private Component component; public Decorator(Component component) { this.component = component; } public void operation() { component.operation(); } } // 定义一个具体的装饰器类,实现了基础功能的扩展 class ConcreteDecorator extends Decorator { public ConcreteDecorator(Component component) { super(component); } public void operation() { super.operation(); System.out.println("ConcreteDecorator.operation()"); } } // 使用示例 public class DecoratorDemo { public static void main(String[] args) { Component component = new ConcreteComponent(); Component decorator = new ConcreteDecorator(component); decorator.operation(); } }
在上面的示例中,Component 接口定义了一个 operation() 方法,被装饰对象 ConcreteComponent 实现了该接口,具有基础功能。
装饰器基类Decorator实现了 Component 接口,维护了一个指向被装饰对象的引用,它的 operation() 方法将调用被装饰对象的 operation() 方法。
具体的装饰器类 ConcreteDecorator 继承了Decorator类,实现了对基础功能的扩展,它的 operation() 方法先调用父类的 operation() 方法,再实现扩展的功能。
在客户端代码中,先创建一个被装饰对象 ConcreteComponent,然后用ConcreteDecorator对象来装饰它,最后调用operation()方法。在执行 operation() 方法时,先调用被装饰对象的 operation() 方法,再执行装饰器类的扩展功能。
最佳实践
假设电商平台上有各种商品可以卖,有些商品需要提供定制化的服务,如礼品包装、定制化贺卡等等。这时候可以使用装饰器模式,对商品进行装饰以提供相应服务。
下面是一个简单的示例:
假设有一个基础商品类 Product,其中包含商品的基本信息,如名称、价格等。同时有一个装饰器类 ProductDecorator,它继承自 Product,并包含一个Product对象作为成员变量,用于装饰商品。具体的装饰器类可以继承 ProductDecorator 并重写其中的方法,实现相应的装饰效果。
// 基础商品类 public class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } } // 装饰器基类 public class ProductDecorator extends Product { protected Product product; public ProductDecorator(Product product) { super(product.getName(), product.getPrice()); this.product = product; } @Override public String getName() { return product.getName(); } @Override public double getPrice() { return product.getPrice(); } } // 礼品包装装饰器 public class GiftWrapDecorator extends ProductDecorator { private static final double GIFT_WRAP_PRICE = 5.0; public GiftWrapDecorator(Product product) { super(product); } @Override public String getName() { return super.getName() + " (gift wrap)"; } @Override public double getPrice() { return super.getPrice() + GIFT_WRAP_PRICE; } } // 定制化贺卡装饰器 public class GreetingCardDecorator extends ProductDecorator { private static final double GREETING_CARD_PRICE = 3.0; private String message; public GreetingCardDecorator(Product product, String message) { super(product); this.message = message; } @Override public String getName() { return super.getName() + " (with greeting card)"; } @Override public double getPrice() { return super.getPrice() + GREETING_CARD_PRICE; } public String getMessage() { return message; } }
在上述代码中,ProductDecorator 作为装饰器的基类,继承自 Product。具体的装饰器类 GiftWrapDecorator 和 GreetingCardDecorator 都继承自 ProductDecorator,并实现其相应的方法,实现相应的装饰效果。其中 GreetingCardDecorator 还包含一个 message 成员变量,用于存储定制化贺卡的内容。这样,当需要对商品进行定制化的服务时,只需要对商品对象进行装饰即可。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲外观模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
- 利用docker搭建es集群
- 一起来学ElasticSearch(一)
- 一起来学ElasticSearch(二)
- 一起来学ElasticSearch(三)
- 一起来学ElasticSearch(四)
- 一起来学ElasticSearch(五)
- 一起来学ElasticSearch(六)
- 一起来学ElasticSearch(七)
- 一起来学ElasticSearch(八)
- 一起来学ElasticSearch(九)
- 一起来学ElasticSearch(十)
- 一起来学ElasticSearch之整合SpringBoot(一)
- 一起来学ElasticSearch之整合SpringBoot(二)
- 一起来学ElasticSearch之整合SpringBoot(三)
项目源码(源码已更新 欢迎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并行流有了解过吗?说说看
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
- springboot-all
地址: github.com/qiuChenglei…- SpringBoot系列教程合集
- 一起来学SpringCloud合集
- SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码模式的服务认证(一)
- SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码模式的服务认证(二)