策略模式
基本介绍
核心思想:把不同算法、不同业务规则封装成不同策略类,运行时根据条件选择使用哪一种策略
它关注的不是 “对象怎么创建”,而是同一个业务动作,有多种不同实现方式
应用场景:假设代码中有大量判断,策略模式可以把每种规则拆成单独的类
实现思路
(1)定义策略接口
(2)定义不同策略实现类
(3)提供策略工厂,便于根据策略枚举获取不同策略实现
⚠️ 注意
在策略比较简单的情况下,我们完全可以用枚举代替策略工厂,通过在枚举类中定义抽象方法,并在每一个枚举对象中实现,合并了定义接口再定义实现类的传统方式,使得代码更简洁,进而简化策略模式
用枚举代替策略工厂
需求分析
高并发场景通过 Redisson 获取锁,但也可能获取失败,此时需要定义获取锁失败后的处理逻辑

代码实现
这里没有单独定义接口和实现类,而是直接用枚举把它们合在一起了
策略接口:MyLockStrategy
具体策略:SKIP_FAST、FAIL_FAST、KEEP_TRYING
java
public enum MyLockStrategy {
SKIP_FAST(){
@Override
public boolean tryLock(RLock lock, MyLock prop) throws InterruptedException {
return lock.tryLock(0, prop.leaseTime(), prop.unit());
}
},
FAIL_FAST(){
@Override
public boolean tryLock(RLock lock, MyLock prop) throws InterruptedException {
boolean isLock = lock.tryLock(0, prop.leaseTime(), prop.unit());
if (!isLock) {
throw new BizIllegalException("请求太频繁");
}
return true;
}
},
KEEP_TRYING(){
@Override
public boolean tryLock(RLock lock, MyLock prop) throws InterruptedException {
lock.lock( prop.leaseTime(), prop.unit());
return true;
}
},
SKIP_AFTER_RETRY_TIMEOUT(){
@Override
public boolean tryLock(RLock lock, MyLock prop) throws InterruptedException {
return lock.tryLock(prop.waitTime(), prop.leaseTime(), prop.unit());
}
},
FAIL_AFTER_RETRY_TIMEOUT(){
@Override
public boolean tryLock(RLock lock, MyLock prop) throws InterruptedException {
boolean isLock = lock.tryLock(prop.waitTime(), prop.leaseTime(), prop.unit());
if (!isLock) {
throw new BizIllegalException("请求太频繁");
}
return true;
}
};
public abstract boolean tryLock(RLock lock, MyLock prop) throws InterruptedException;
}应用示例
java
@Component
@Aspect
@RequiredArgsConstructor
public class MyLockAspect implements Ordered {
private final MyLockFactory lockFactory;
@Around("@annotation(myLock)")
public Object tryLock(ProceedingJoinPoint pjp, MyLock myLock) throws Throwable {
// 1.创建锁对象
RLock lock = lockFactory.getLock(myLock.lockType(), myLock.name());
// 2.尝试获取锁
boolean isLock = myLock.lockStrategy().tryLock(lock, myLock);
// 3.判断是否成功
if(!isLock) {
// 3.1.失败,快速结束
return null;
}
try {
// 3.2.成功,执行业务
return pjp.proceed();
} finally {
// 4.释放锁
lock.unlock();
}
}
@Override
public int getOrder() {
return 0;
}
}