1静态工厂模式
1.1.提供了一种创建对象的方式,将对象的创建过程封装在一个工厂类中,而不是直接在客户端代码中实例化对象。
1.2解决创建对象和销毁对象的操作 。 使用时仅需 factory.getXXX 即可获得相应的对象,不需要再管理创建销毁对象。
2.策略模式
根据不同的业务场景可以自定义不同的策略和算法,减少代码的耦合性,
3. 静态工厂 + 策略模式,
自动实现 策略的的注册和使用,无需改动现有的代码即可实现 策略新增和对象创建
3.1 具体代码实现方式
(1) 注册全局静态变量和自定义注解 (注解的目的为 无需 实现 implements Strategy )
public class SysConstant {
public static final String PACKAGE_NAME = "com.hzq.test";
// 策略模板
public static final Map<String, BusinessStrategy> STRATEGY_CENTER = Maps.newConcurrentMap();
}
自定义注解,便于静态工厂扫描对应的策略,无需 手动注册
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BusinessType {
String value();
}
自定义接口 ,当 后续需要新增的 策略 需要根据 基础的 超类 接口定义实现( 其他的策略都是当前策略的多态)
import java.util.List;
public interface BusinessStrategy {
}
(2) 建立业务策略静态工厂,对于不同的 业务进行注册 后面使用时只要注入静态工厂后,根据业务类型即可拿出对应的策略
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import com.eforkrobot.modules.wcs.common.annotation.BusinessType;
import com.eforkrobot.modules.wcs.common.constant.SysConstant;
import org.springframework.stereotype.Component;
import java.util.Set;
/**
* @Author:
* @Date:
* @Description: 业务策略工厂
**/
@Component
public class BusinessStrategyFactory {
// 默认业务策略
public BusinessStrategy getDefaultStrategy() {
return new BaseValidateStrategy();
}
public BusinessStrategy getStrategy(String businessType) {
return SysConstant.STRATEGY_CENTER.computeIfAbsent(businessType, k -> new BaseValidateStrategy());
}
// 注册业务策略
public static void registerStrategy(String businessType, BusinessStrategy strategy) {
SysConstant.STRATEGY_CENTER.put(businessType, strategy);
}
static {
Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(SysConstant.PACKAGE_NAME, BusinessType.class);
for (Class<?> clazz : classes) {
BusinessType annotation = clazz.getAnnotation(BusinessType.class);
SysConstant.STRATEGY_CENTER.put(annotation.value(), (BusinessStrategy) ReflectUtil.newInstance(clazz));
}
}
}
tip: 优化 将 策略注册交个spring管理,防止策略中报异常导致事务失效的 现象
@PostConstruct
public void initStrategies() {
// 从Spring容器中获取所有带有@BusinessType注解的Bean
Map<String, Object> strategyBeans = applicationContext.getBeansWithAnnotation(BusinessType.class);
strategyBeans.forEach((beanName, bean) -> {
if (bean instanceof BusinessStrategy) {
Class<?> clazz = bean.getClass();
BusinessType annotation = clazz.getAnnotation(BusinessType.class);
if (annotation != null) {
// 这里存储的是Spring管理的Bean,包含AOP代理
registerStrategy(annotation.value(), (BusinessStrategy) bean);
}
}
});
}
默认策略模板 -- 可以自定义一个
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
* @Author:
* @Date:
* @Description:
**/
@RequiredArgsConstructor
@Component
@Slf4j
public class BaseValidateStrategy implements BusinessStrategy {
}
(3) 使用时只需要 注入 factory 即可,无需 再关注 策略方法 对象创建 以后只需要修改策略 即可,无需修改业务代码
private final BusinessStrategyFactory factory;
BusinessStrategy strategy = factory.getDefaultStrategy();
List<BusinessTicketBO> businessTickets = strategy.containerValidate(businessTicketBOList);