策略模式实例

需求描述

购买手机分为三个手机厂商:华为手机、小米手机、OPPO手机,根据每个手机厂商编码查看对应厂商旗舰手机。

代码实现

初始化容器配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* 初始化配置容器
*
* @author leizi
* @date 2024/03/17
*/
@Component
@Slf4j
public class AppContext implements ApplicationContextAware {
private static ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (null == appContext) {
if (null != applicationContext) {
AppContext.appContext = applicationContext;
}
log.info("Spring init successfully");
}
}
public static ApplicationContext getContext() {
if (appContext == null) {
throw new IllegalStateException("applicationContext inject failure,please restart the service");
}
return appContext;
}
}

厂商类型枚举

/**
* 手机厂商枚举
*
* @author leizi
* @date 2024/03/17
*/
public enum SourceTypeEnum {
HUAWEI(1, "华为厂商"),
XIAOMI(2, "小米厂商"),
OPPO(3, "OPPO厂商");
private Integer type;
private String memo;
SourceTypeEnum(Integer type, String memo) {
this.type = type;
this.memo = memo;
}
public Integer getType() {
return type;
}
public String getMemo() {
return memo;
}
/**
* 根据类型获取实例
*
* @param type
* @return
*/
public static SourceTypeEnum getInstance(Integer type) {
if (null == type) {
return null;
}
for (SourceTypeEnum typeEnum : SourceTypeEnum.values()) {
if (typeEnum.type.equals(type)) {
return typeEnum;
}
}
return null;
}
}

策略来源注解

import com.example.demo.enums.SourceTypeEnum;
import org.springframework.stereotype.Component;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 厂商来源注解
*
* @author leizi
* @date 2024/03/17
*/
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface SourceType {
SourceTypeEnum value();
}

厂商来源工厂配置

/**
* @author leizi
* @date 2024/03/18
*/
public interface InitProcess {
/**
* 初始化工厂
*/
void init();
}
import cn.hutool.core.map.MapUtil;
import com.example.demo.annotation.SourceType;
import com.example.demo.enums.SourceTypeEnum;
import com.example.demo.service.PhoneManufacturerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author leizi
* @date 2024/03/17
*/
@Component
@Slf4j
public class FactoryHandlerStrategy implements InitProcess {
private static ConcurrentHashMap<SourceTypeEnum, PhoneManufacturerService> phoneManufacturerMap = new ConcurrentHashMap<>();
@Override
public void init() {
initPhoneManufacturer();
}
/**
* 初始化phoneManufacturerMap
*/
private void initPhoneManufacturer() {
// 加载PhoneManufacturerService 厂商处理实现类
Map<String, PhoneManufacturerService> mapPhoneManufacturer = AppContext.getContext().getBeansOfType(PhoneManufacturerService.class);
mapPhoneManufacturer.entrySet().stream().forEach(entry -> {
Class<? extends Object> clazz = entry.getValue().getClass();
SourceType annotation = clazz.getAnnotation(SourceType.class);
/*if (null == annotation) {
// 这里为处理方法使用@Async,SourceType类型获取失效问题
Map<String, Object> map = JSON.parseObject(JSON.toJSONString(entry.getValue()));
Object decoratedClass = map.get("decoratedClass");
try {
clazz = Class.forName(decoratedClass.toString());
annotation = clazz.getAnnotation(SourceType.class);
} catch (Exception e) {
log.error("class forName error:{}", e);
}
}*/
if (null == annotation) {
return;
}
SourceTypeEnum sourceType = annotation.value();
if (null != sourceType) {
PhoneManufacturerService phoneManufacturerService = phoneManufacturerMap.get(sourceType);
if (null != phoneManufacturerService) {
phoneManufacturerMap.remove(sourceType);
}
phoneManufacturerMap.put(sourceType, entry.getValue());
}
});
}
/**
* 根据厂商来源获取实现类
*
* @param sourceType
* @return
*/
public PhoneManufacturerService getPhoneManufacturer(SourceTypeEnum sourceType) {
if (MapUtil.isEmpty(phoneManufacturerMap)) {
initPhoneManufacturer();
}
return phoneManufacturerMap.get(sourceType);
}
}

初始化来源工厂配置

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* 初始配置
*
* @author leizi
* @date 2024/03/18
*/
@Component
public class InitContext implements ApplicationRunner {
private final FactoryHandlerStrategy factoryHandlerStrategy;
public InitContext(FactoryHandlerStrategy factoryHandlerStrategy) {
this.factoryHandlerStrategy = factoryHandlerStrategy;
}
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
/*
* 容器启动完成把实现InitProcess实现类都执行init初始化操作,根据实际需要实现
* */
// Map<String, InitProcess> processMap = AppContext.getContext().getBeansOfType(InitProcess.class);
factoryHandlerStrategy.init();
}
}

业务代码

/**
* @author leizi
* @date 2024/03/17
*/
public interface PhoneManufacturerService {
/**
* 根据厂商类型查看手机
*
* @param type 厂商类型
* @return
*/
String getPhone(Integer type);
/**
* 购买指定厂商手机
*
* @param type 厂商类型
* @return
*/
String buyPhone(Integer type);
}
import com.example.demo.annotation.SourceType;
import com.example.demo.enums.SourceTypeEnum;
import com.example.demo.service.PhoneManufacturerService;
/**
* OPPO厂商手机
*
* @author leizi
* @date 2024/03/17
*/
@SourceType(SourceTypeEnum.OPPO)
public class OppoManufacturerServiceImpl implements PhoneManufacturerService {
@Override
public String getPhone(Integer type) {
return "一台OPPOFindX500旗舰手机";
}
@Override
public String buyPhone(Integer type) {
return "购买了OPPOFindX500旗舰手机";
}
}
import com.example.demo.annotation.SourceType;
import com.example.demo.enums.SourceTypeEnum;
import com.example.demo.service.PhoneManufacturerService;
/**
* 小米厂商手机
*
* @author leizi
* @date 2024/03/17
*/
@SourceType(SourceTypeEnum.XIAOMI)
public class XiaomiManufacturerServiceImpl implements PhoneManufacturerService {
@Override
public String getPhone(Integer type) {
return "一台小米100pro旗舰手机";
}
@Override
public String buyPhone(Integer type) {
return "购买了小米100pro旗舰手机";
}
}
import com.example.demo.annotation.SourceType;
import com.example.demo.enums.SourceTypeEnum;
import com.example.demo.service.PhoneManufacturerService;
/**
* 华为厂商手机
*
* @author leizi
* @date 2024/03/17
*/
@SourceType(SourceTypeEnum.HUAWEI)
public class HuaweiManufacturerServiceImpl implements PhoneManufacturerService {
@Override
public String getPhone(Integer type) {
return "一台华为Mete100旗舰手机";
}
@Override
public String buyPhone(Integer type) {
return "购买了华为Mete100旗舰手机";
}
}
import com.example.demo.config.FactoryHandlerStrategy;
import com.example.demo.enums.SourceTypeEnum;
import com.example.demo.service.PhoneManufacturerService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author leizi
* @date 2024/03/17
*/
@RestController
@RequestMapping("/phone")
public class PhoneController {
private final FactoryHandlerStrategy factoryHandlerStrategy;
public PhoneController(FactoryHandlerStrategy factoryHandlerStrategy) {
this.factoryHandlerStrategy = factoryHandlerStrategy;
}
@GetMapping("/get")
public String getPhone(@RequestParam Integer type) {
PhoneManufacturerService manufacturerService = factoryHandlerStrategy.getPhoneManufacturer(SourceTypeEnum.getInstance(type));
if (null != manufacturerService) {
return manufacturerService.getPhone(type);
}
return "获取失败了";
}
}
posted @   Lz_蚂蚱  阅读(15)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起