设计模式组合-2--工厂模式+策略模式+模板方法 +泛型+IOC机制

38 阅读1分钟
public abstract class AbstractGamingHandler<Req> {

    @Autowired
    WebSocketService webSocketService;
    @Autowired
    RoomService roomService;

    @Autowired
    PlayerStatusService playerStatusService;
    private Class<Req> bodyClass;

    @PostConstruct
    private void init() {
        ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.bodyClass = (Class<Req>) genericSuperclass.getActualTypeArguments()[0];
        GamingHandlerFactory.register(getTypeEnum().getStatus(), this);
    }

    @Transactional
    public void saveAndSend(GamingReq req, Long uid) throws Exception {
        // 持久化验证
        checkStatus(req, uid);
        Req bean = toBean(req.getBody());
        //创建转发消息
        WSBaseResp save = buildWSResp(req, uid, bean);
        //直接转发消息
        webSocketService.sendToUid(save, getUids(req.getRoomId()));
    }

    abstract WSBaseResp buildWSResp(GamingReq req, Long uid, Req body);

    List<Long> getUids(@NotNull Long roomId) {
        List<Long> broadcastIds = roomService.getTwoPlayer(roomId);
        return broadcastIds;
    }

    void checkStatus(GamingReq req, Long uid) throws Exception {
        // 验证状态
        if (false) {
            throw new Exception("错误");
        }
    }

    private Req toBean(Object body) {
        if (bodyClass.isAssignableFrom(body.getClass())) {
            return (Req) body;
        }
        return BeanUtil.toBean(body, bodyClass);
    }

    abstract GamingEnum getTypeEnum();

    abstract WSRespTypeEnum getWSRespTypeEnum();

    public WSBaseResp WSAdapter(Object data) {
        return WSBaseResp.build(getWSRespTypeEnum(), data);
    }

}
package com.example.demo.game.biz.strategy;

import com.example.demo.common.redis.RedisKeys;
import com.example.demo.common.redis.RedisUtil;
import com.example.demo.game.biz.BizGameService;
import com.example.demo.game.model.dto.ChallengeDto;
import com.example.demo.game.model.dto.GamingReq;
import com.example.demo.web.enums.GamingEnum;
import com.example.demo.websocket.model.WSBaseResp;
import com.example.demo.websocket.model.enums.WSRespTypeEnum;
import com.example.demo.websocket.model.vo.ChallengeData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

// 求和处理类
@Component
public class ChallengeReqHandler extends AbstractGamingHandler<ChallengeDto> {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    BizGameService bizGameService;

    @Override
    WSBaseResp buildWSResp(GamingReq req, Long uid, ChallengeDto body) {
        ChallengeData challengeData = new ChallengeData();
        redisUtil.set(RedisKeys.GAME_CHESS_UNDO + req.getRoomId(), req.getRoomId());
        return WSAdapter(challengeData);
    }

    @Override
    public GamingEnum getTypeEnum() {
        return GamingEnum.CHALLENGE;
    }

    @Override
    WSRespTypeEnum getWSRespTypeEnum() {
        return WSRespTypeEnum.CHALLENGE;
    }

}
@AllArgsConstructor
@Getter
public enum GamingEnum {

    //接受悔棋,拒绝悔棋,
    REDO_REQUEST(1, "悔棋请求", RedoReqDto.class),
 
    ;


    private static final Map<Integer, GamingEnum> cache;

    static {
        cache = Arrays.stream(GamingEnum.values()).collect(Collectors.toMap(GamingEnum::getStatus, Function.identity()));
    }

    private final Integer status;
    private final String desc;
    private final Class<?> dataClass;

    public static GamingEnum of(Integer type) {
        return cache.get(type);
    }

    public <T> AbstractGamingHandler<T> getHandler() {
        return GamingHandlerFactory.getStrategyNoNull(this.getStatus());
    }
    
}
public class GamingHandlerFactory {
    private static final Map<Integer, AbstractGamingHandler<?>> STRATEGY_MAP = new HashMap<>();

    public static void register(Integer code, AbstractGamingHandler strategy) {
        STRATEGY_MAP.put(code, strategy);
    }

    public static AbstractGamingHandler getStrategyNoNull(Integer code) {
        AbstractGamingHandler strategy = STRATEGY_MAP.get(code);
        return strategy;
    }

}