前言
目前正在出一个设计模式专题
系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的装饰器模式
,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以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 实现授权码模式的服务认证(二)