項目運用中的設計模式--策略模式,工廠模式

運用場景

APP端需要展示彙總信息,從各個子模塊抽取相應數量的數據展示。
各個子模塊的功能接口都存在,移動端挨個調用也可完成操作,單本着業務處理服務端處理的原則,我決定合併子模塊的結果集,統一調用展示這也是外觀模式的變種吧!

業務梳理

  1. 整合統一的接口處理;
  2. 工廠模式封裝鎖需要的結果;
  3. CyclicBarrier等多線程手段,並行請求接口數據併合並多線程後返回的結果,統一返回移動端。

業務應用–策略模式,工廠模式

  1. 定義用於請求數據的接口,可拓展參數,此處的請求需要token從外界傳入;
public interface UserFunctionStrategy {
    /**
     * 請求獲取用戶的功能信息
     * @return
     */
    Object getUserFunctionFromUrl(String token);
}
  1. 實現接口,規整請求數據或者業務處理
public class UserFunctionStrategyImpl implements UserFunctionStrategy {
    private UserFunctionEnum userFunctionEnum;
    @Override
    public Object getUserFunctionFromUrl(String token) {
        JSONObject requestJson = new JSONObject();
        requestJson.put("token", token);
        String requestParam = userFunctionEnum.getRequestParam();
        if(!StringUtils.isEmpty(requestParam)){
            requestJson.put(requestParam.split("_")[0],requestParam.split("_")[1]);
        }
        return WmsCrawUtil.requestResultData(userFunctionEnum.getUrl(), requestJson);
    }

    public UserFunctionStrategyImpl(UserFunctionEnum userFunctionEnum){
        this.userFunctionEnum = userFunctionEnum;
    }
}
  1. 新增工廠類,初始化各個子模塊請求枚舉,方便後期調用,避免太長的if-else
public class FunctionFactory {

    private static FunctionFactory functionFactory = new FunctionFactory();
    private FunctionFactory(){
    }
    private static Map<String, UserFunctionStrategyImpl> strategyMap = new HashMap<>();
    static{
        strategyMap.put(UserFunctionEnum.HTXX.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.HTXX));
        strategyMap.put(UserFunctionEnum.LLJH.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.LLJH));
        strategyMap.put(UserFunctionEnum.YHJH.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.YHJH));
        strategyMap.put(UserFunctionEnum.YLLD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.YLLD));
        strategyMap.put(UserFunctionEnum.ZJD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.ZJD));

        strategyMap.put(UserFunctionEnum.PDD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.PDD));
        strategyMap.put(UserFunctionEnum.YHD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.YHD));
        strategyMap.put(UserFunctionEnum.YTPD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.YTPD));
        strategyMap.put(UserFunctionEnum.JHRWZX.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.JHRWZX));
        strategyMap.put(UserFunctionEnum.SJRWZX.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.SJRWZX));
        strategyMap.put(UserFunctionEnum.ZXDTZYD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.ZXDTZYD));
        strategyMap.put(UserFunctionEnum.ZJDRW.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.ZJDRW));
        strategyMap.put(UserFunctionEnum.YSHD.getCode(), new UserFunctionStrategyImpl(UserFunctionEnum.YSHD));
    }
    public UserFunctionStrategy creator(String type){
        return strategyMap.get(type);
    }
    public static FunctionFactory getInstance(){
        return functionFactory;
    }
}
  1. 使用多線程請求獲取各個模塊數據,避免了繁雜的if-else判斷操作
    public JSONObject userFunction(Long userId, String type, String token){
        long time = System.currentTimeMillis();
        List<AppUserRole> appUserRoles = userMenus(userId, type);
        JSONObject userFunction = new JSONObject();
        //用於檢查線程是否結束
        final BooleanWithMsg booleanWithMsg = BooleanWithMsg.False("未完成");
        //需要等待的線程數
        final CyclicBarrier barrier=new CyclicBarrier(appUserRoles.size(), () -> booleanWithMsg.setSuccess(true));
        //並行觸發任務請求
        appUserRoles.forEach(appUserRole -> {
            String roleCode = appUserRole.getCode();
            executorService.execute(() -> {
                Object roleData = callUrlData(roleCode, token);
                if(roleData != null){
                    userFunction.put(roleCode,roleData);
                }
                try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        });
        //檢查是否結束
        while(true){
            try {
                Thread.sleep(100L);
                if(booleanWithMsg.isSuccess() || System.currentTimeMillis()-time > 20000){
                    return userFunction;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                return userFunction;
            }
        }
    }
    /**
     * 獲取用於請求數據的工具
     * @param code 編碼
     * @return
     */
    private Object callUrlData(String code, String token){
        UserFunctionStrategy userFunctionStrategy = FunctionFactory.getInstance().creator(code);
        return userFunctionStrategy.getUserFunctionFromUrl(token);
    }
  1. 最後將數統一返回,該方法最大限度優化了數據請求時間,但是也是有水桶效應的,後期再添加相應的子模塊可以修改工廠類以及相應的枚舉類型就可以完成添加,拓展性增強。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章