使用註解實現策略模式

需求描述

現在我們有一個接受供應商訂單狀態通知的接口,目前支持的功能有退款,改簽,後續可能需要接入新功能,比如航變,訂單狀態改變之類。接口的請求格式一致,接口如下:

請求

package com.ahut.contract.flight;

/**
 * @desc : 供應商通知請求
 * @author : cheng
 * @date : 2019-03-04 21:18
 */
public class VendorOrderNotifyRequest {

    /**
     * 數據
     */
    private String data;
    /**
     * 依據tag判斷事件類型
     */
    private String tag;
    /**
     * 創建時間
     */
    private long createTime;
    /**
     * 簽名
     */
    private String sign;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }
}

響應

package com.ahut.contract.flight;

/**
 * @desc : 供應商通知響應
 * @author : cheng
 * @date : 2019-03-04 21:21
 */
public class VendorOrderNotifyResponse {

    private int code;

    private String message;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

請求統一入口接口

package com.ahut.flight.service;

import com.ahut.contract.flight.VendorOrderNotifyRequest;
import com.ahut.contract.flight.VendorOrderNotifyResponse;

/**
 * @desc :
 * @author : cheng
 * @date : 2019-03-04 21:16
 */
public interface VendorOrderNotifyService {

    /**
     * @desc : 
     * @author : cheng
     * @date : 2019-03-04 21:24
     */
    VendorOrderNotifyResponse orderNotify(VendorOrderNotifyRequest request);

}

使用if/switch

package com.ahut.flight.service.impl;

import com.ahut.contract.flight.VendorOrderNotifyRequest;
import com.ahut.contract.flight.VendorOrderNotifyResponse;
import com.ahut.flight.service.OrderNotifyContextService;
import com.ahut.flight.service.OrderNotifyHandleService;
import com.ahut.flight.service.VendorOrderNotifyService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class VendorOrderNotifyServiceImpl implements VendorOrderNotifyService {

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-04 21:25
     */
    @Override
    public VendorOrderNotifyResponse orderNotify(VendorOrderNotifyRequest request) {
        String tag = Optional.ofNullable(request).map(VendorOrderNotifyRequest::getTag).orElse("");
        if (StringUtils.equals(tag, "change")) {
            // 改簽
        } else if (StringUtils.equals(tag, "refund")) {
            // 退款
        } else {
            // 不支持
        }

        switch (tag) {
            case "change":
                // 改簽
                break;
            case "refund":
                // 退款
                break;
                default:
                    // 不支持
        }
        return null;
    }

}

缺點:代碼不靈活,下次新增功能時,需要修改現有代碼(增加if分支或者switch分支)

使用註解 + 策略模式

定義註解

package com.ahut.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @desc :
 * @author : cheng
 * @date : 2019-03-04 21:56
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestTag {

    public String value() default "";

}

定義處理請求data的統一接口

package com.ahut.flight.service;


import com.ahut.contract.flight.VendorOrderNotifyResponse;

/**
 * @desc : 處理請求
 * @author : cheng
 * @date : 2019-03-04 21:29
 */
public interface OrderNotifyHandleService {

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-04 21:46
     */
    VendorOrderNotifyResponse orderNotify(String data);

}

實現統一接口,退款,使用自定義註解

package com.ahut.flight.service.impl;


import com.ahut.common.annotation.RequestTag;
import com.ahut.contract.flight.VendorOrderNotifyResponse;
import com.ahut.flight.service.OrderNotifyHandleService;
import org.springframework.stereotype.Service;

/**
 * @desc : 退款
 * @author : cheng
 * @date : 2019-03-04 21:50
 */
@Service("RefundNotifyHandleServiceImpl")
@RequestTag("refund")
public class RefundNotifyHandleServiceImpl implements OrderNotifyHandleService {

    /**
     * @desc : 
     * @author : cheng
     * @date : 2019-03-04 22:11
     */
    @Override
    public VendorOrderNotifyResponse orderNotify(String data) {
        VendorOrderNotifyResponse response = new VendorOrderNotifyResponse();
        response.setCode(0);
        response.setMessage("處理退票通知");
        return response;
    }
}

實現統一接口,改簽,使用自定義註解

package com.ahut.flight.service.impl;

import com.ahut.common.annotation.RequestTag;
import com.ahut.contract.flight.VendorOrderNotifyResponse;
import com.ahut.flight.service.OrderNotifyHandleService;
import org.springframework.stereotype.Service;

/**
 * @desc : 改簽
 * @author : cheng
 * @date : 2019-03-04 21:50
 */
@Service("ChangeNotifyHandleServiceImpl")
@RequestTag("change")
public class ChangeNotifyHandleServiceImpl implements OrderNotifyHandleService {

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-04 22:04
     */
    @Override
    public VendorOrderNotifyResponse orderNotify(String data) {
        VendorOrderNotifyResponse response = new VendorOrderNotifyResponse();
        response.setCode(0);
        response.setMessage("處理改簽通知");
        return response;
    }
}

實現統一接口,不支持的tag,使用自定義註解

package com.ahut.flight.service.impl;

import com.ahut.common.annotation.RequestTag;
import com.ahut.contract.flight.VendorOrderNotifyResponse;
import com.ahut.flight.service.OrderNotifyHandleService;
import org.springframework.stereotype.Service;

/**
 * @desc : 不支持
 * @author : cheng
 * @date : 2019-03-05 22:11
 */
@Service("NonSupportNotifyHandleServiceImpl")
@RequestTag("nonsupport")
public class NonSupportNotifyHandleServiceImpl implements OrderNotifyHandleService {

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-05 22:12
     */
    @Override
    public VendorOrderNotifyResponse orderNotify(String data) {
        VendorOrderNotifyResponse response = new VendorOrderNotifyResponse();
        response.setCode(0);
        response.setMessage("不支持的通知");
        return response;
    }
}

定義上下文接口,依據tag,返回具體的處理實例

package com.ahut.flight.service;

/**
 * @desc : 上下文
 * @author : cheng
 * @date : 2019-03-04 21:27
 */
public interface OrderNotifyContextService {

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-04 22:04
     */
    OrderNotifyHandleService getContext(String tag);

}

上下文實現

package com.ahut.flight.service.impl;

import com.ahut.common.annotation.RequestTag;
import com.ahut.flight.service.OrderNotifyContextService;
import com.ahut.flight.service.OrderNotifyHandleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @desc : 上下文
 * @author : cheng
 * @date : 2019-03-04 22:05
 */
@Service
public class OrderNotifyContextServiceImpl implements OrderNotifyContextService {

    @Autowired
    private List<OrderNotifyHandleService> handleServiceList;

    @Resource(name = "NonSupportNotifyHandleServiceImpl")
    private OrderNotifyHandleService nonsupportService;

    @Override
    public OrderNotifyHandleService getContext(String tag) {
        if (StringUtils.isBlank(tag)) {
            return nonsupportService;
        }

		// 對比註解中的value和tag
        OrderNotifyHandleService handleService = handleServiceList.stream()
                .filter(f -> StringUtils.equals(tag, f.getClass().getAnnotation(RequestTag.class).value()))
                .findFirst()
                .orElse(nonsupportService);

        return handleService;
    }
}

實現請求統一入口

package com.ahut.flight.service.impl;

import com.ahut.contract.flight.VendorOrderNotifyRequest;
import com.ahut.contract.flight.VendorOrderNotifyResponse;
import com.ahut.flight.service.OrderNotifyContextService;
import com.ahut.flight.service.OrderNotifyHandleService;
import com.ahut.flight.service.VendorOrderNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class VendorOrderNotifyServiceImpl implements VendorOrderNotifyService {

	/**
	 * 持有上下文
	 */
    @Autowired
    private OrderNotifyContextService contextService;

    /**
     * @desc :
     * @author : cheng
     * @date : 2019-03-04 21:25
     */
    @Override
    public VendorOrderNotifyResponse orderNotify(VendorOrderNotifyRequest request) {
        String tag = Optional.ofNullable(request).map(VendorOrderNotifyRequest::getTag).orElse("");
        OrderNotifyHandleService handleService = contextService.getContext(tag);
        VendorOrderNotifyResponse response = handleService.orderNotify(request.getData());
        return response;
    }

}

總結

增加了代碼的靈活性
符合開閉原則
新增功能時,不用修改原有的代碼,直接實現接口即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章