前言
目前正在出一个设计模式专题
系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的代理模式
,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java
语言为主, 好了, 废话不多说直接开整吧~
代理模式
代理模式
是一种常见的设计模式,它为其他对象提供了一种代理
以控制对这个对象的访问。
在代理模式
中,我们定义了一个代理类,代理类持有一个真正执行业务逻辑的对象的引用,客户端调用代理对象的方法时,实际上是在调用真正对象的方法,代理对象可以在调用真正对象的方法前后进行一些处理,如记录日志、缓存结果、权限校验等。
下面我们通过一个简单的示例来说明代理模式的使用。
假设我们正在开发一个简单的视频播放器,播放器支持播放本地视频和网络视频,我们需要对网络视频进行一个简单的权限校验,只有购买了该视频的用户才能播放。此时我们可以使用代理模式来实现。
首先,我们定义一个视频接口 Video
,该接口有一个播放方法:
public interface Video { void play(); }
接下来,我们定义一个本地视频类 LocalVideo
和一个网络视频类 NetworkVideo
,它们都实现了 Video
接口:
public class LocalVideo implements Video { private String filePath; public LocalVideo(String filePath) { this.filePath = filePath; } @Override public void play() { System.out.println("Playing local video: " + filePath); } } public class NetworkVideo implements Video { private String url; public NetworkVideo(String url) { this.url = url; } @Override public void play() { System.out.println("Playing network video: " + url); } }
我们需要为网络视频实现一个代理类,来实现权限校验。代理类NetworkVideoProxy
实现了 Video
接口,持有一个NetworkVideo
对象:
public class NetworkVideoProxy implements Video { private NetworkVideo networkVideo; public NetworkVideoProxy(NetworkVideo networkVideo) { this.networkVideo = networkVideo; } @Override public void play() { // 模拟权限校验 boolean hasPermission = checkPermission(); if (hasPermission) { networkVideo.play(); } else { System.out.println("You do not have permission to play this video."); } } private boolean checkPermission() { // 模拟权限校验 return true; } }
最后,我们在客户端代码中使用视频对象和代理对象:
public class Client { public static void main(String[] args) { // 播放本地视频 Video localVideo = new LocalVideo("sample.mp4"); localVideo.play(); // 播放网络视频 NetworkVideo networkVideo = new NetworkVideo("https://example.com/sample.mp4"); Video networkVideoProxy = new NetworkVideoProxy(networkVideo); networkVideoProxy.play(); } }
在这个示例中,我们使用代理模式实现了对网络视频的权限校验,代理对象 NetworkVideoProxy
控制了对 NetworkVideo
对象的访问,并在访问前进行了权限校验
最佳实践
电商平台中常见的使用代理模式
的场景是实现缓存代理。
在电商平台中,商品信息的获取是一个比较耗时的操作,而且多次获取的结果往往是相同的。为了避免频繁地向数据库请求,可以采用缓存的方式,将已经获取到的商品信息存储在内存中,下次需要获取的时候直接从内存中读取,提高了系统的响应速度。
这个场景可以使用代理模式
来实现。具体实现过程是:
创建商品信息的接口 ProductService
,其中包含了获取商品信息的方法 getProductInfo
。
public interface ProductService { ProductInfo getProductInfo(Long productId); }
创建商品信息的实现类 ProductServiceImpl
,并在其中添加缓存代理的逻辑。
public class ProductServiceImpl implements ProductService { private final Map<Long, ProductInfo> productCache = new HashMap<>(); private final ProductService productService; public ProductServiceImpl(ProductService productService) { this.productService = productService; } @Override public ProductInfo getProductInfo(Long productId) { ProductInfo productInfo = productCache.get(productId); if (productInfo != null) { System.out.println("Get product info from cache: " + productId); return productInfo; } productInfo = productService.getProductInfo(productId); productCache.put(productId, productInfo); return productInfo; } }
在ProductServiceImpl
类中,创建了一个缓存代理,如果缓存中已经存在了需要获取的商品信息,则直接从缓存中读取,否则调用实际的商品信息获取方法获取商品信息,并将其存入缓存中。
public class Client { public static void main(String[] args) { ProductService productService = new ProductServiceImpl(new ProductAServiceImpl()); ProductService proxy = new ProductServiceImpl(productService); ProductInfo productInfo = proxy.getProductInfo(123L); System.out.println("Product info: " + productInfo); } }
在客户端中,创建了一个 ProductService
的实现类的实例,然后再将其传递给代理类 ProductServiceImpl
的构造方法中,创建代理对象 proxy
。最后通过代理对象调用getProductInfo
方法来获取商品信息。
使用代理模式
可以将缓存代理的逻辑
与商品信息的获取逻辑分离
开来,使得代码更加清晰,易于维护。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲责任链模式
~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注
鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
项目源码(源码已更新 欢迎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 实现授权码模式的服务认证(二)