首页
搜索 搜索
关注

环球热消息:你用过哪些设计模式(一)?

2023-06-28 09:35:03 博客园

什么是设计模式?

一些经验总结的最佳实践!


(相关资料图)

是不是必须要用?

并不是,但是既然已经说是最佳实践了,该用的地方,你不用,就有些违背常理了。

一、单例

这个或许是最最最常见,也是最最最常用的了。

为什么要用单例模式?

因为只需要一个对象就够了(有时候只能有一个,有时候是不需要有多个)。

对象的创建和销毁也是成本。

1、Kafka 消息发送

比如,你要发 kafka 消息,你要创建一个 Producer 对象,因为是 Producer 线程安全的,所以一般创建一个对象就够了。

借用官方的一个建议:

"The producer is thread safe and sharing a single producer instance across threads will generally be faster than having multiple instances."

2、Spring 容器 bean

Spring 容器管理的对象默认创建模式为单例。当然你也可以根据实际业务对不同的对象设置不同的创建模式。

singleton: (Default) Scopes a single bean definition to a single object instance for each Spring IoC container.

需要说明的是,这个单例只是针对一个容器。

3、本地缓存

使用 Guava 本地缓存来加速业务响应。这个对于一个业务模块也只需要创建一个,否则就会发生混乱了。

4、线程池

grpc 的线程池。

二、门面

门面模式或者也叫外观模式。

意在屏蔽复杂性,通过一个简洁的门面与外界进行交互。

1、信息输出

比如,另外一个客服系统需要调取系列的用户信息,包括基本信息,注册、登录信息,粉丝、关注信息,认证信息等等。

对于业务组来说,可能每一项都有现成的接口输出。

但是,如果直接将这么老多接口直接丢出去,似乎也显得有些不合适:信息整合容易出问题;繁多的接口交互浪费网络资源,影响业务响应时延,也容易破坏信息展现的完整性。

这里就可以将所需的不同信息接口逻辑进行整体的封装,输出一个单一的功能接口来做门面接口。

2、Netty 的 Channel

Channel是一个接口,而且是一个很大的接口,我们称之为“大而全”,囊括了server端及client端接口所需要的接口。

Channel是一个门面,封装了包括网络I/O及相关的所有操作。

Channel聚合了包括网络读写、链路管理、网络连接信息、获取EventLoop、Pipeline等相关功能类;统一分配,调度实现相应场景的功能。

3、BeanDefinitionLoader

BeanDefinitionLoader 用于从底层资源加载 bean 定义信息,包括 xml、JavaConfig。

是基于 AnnotatedBeanDefinitionReader、XmlBeanDefinitionReader、ClassPathBeanDefinitionScanner 的门面模式。

三、观察者

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式

1、Guava EventBus

用户信息修改后刷新整体缓存。

为什么使用它?

首先是异步需求:同步有针对性的信息修改。整体刷新逻辑作为缓存一致性数据保障不应该占用同步业务逻辑。

其次是解耦:用户信息比较冗繁,相应的 reload 逻辑牵涉业务甚多。所以将这部分逻辑进行解耦分离。

2、ApplicationListener

Spring ApplicationListener 应用事件监听接口,基于标准的 EventListener 接口,观察者模式实现。

ApplicationContext 通过 ApplicationEvent 类及 ApplicationListener 接口来处理事件。容器内实现了 ApplicationListener 接口的对象能够获取任何 ApplicationEvent 发布的事件。

四、策略

将军,我这里有锦囊三个,你且随身带着,路遇天门,打开锦囊一,得扣天门;路遇地门,打开锦囊二,得扣地门;路遇人门,打开锦囊三,得扣人门。

策略模式针对同一应用场景存在多种处理方式的情景。

1、发短信

一个公司会接很多外部短信通道,阿里、Tencent、Twilio 等。

发送方可能会指定特定的短信通道;发送手机号可能地属国内或者或外;

针对这种应用场景,就可以根据相应的入参选取不同的短信通道执行相应的发送操作。

3、行为验证

针对不同用户风险特征,执行不同的安全级别验证。

极验验证的滑块、点选、语序、空间推理等。

3、JDK Comparator

Collections.sort(Listlist, Comparator c)

根据传入的 Comparator 比较器对相应的列表进行排序