设计模式 - 静态工厂模式 + 策略模式,
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管理,防止策略中报异常导致事务失效的 现象
@PostConstructpublic void initStrategies() {// 从Spring容器中获取所有带有@BusinessType注解的BeanMap<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);