在刚接触设计模式时,在视频中的理论总会学了就忘,原因就是没有具体的应用场景,导致没有理解到其中的原理。今天在工作中正好遇到了策略模式的具体应用,所以记录一下!

先来说一下策略模式的基本原理吧!策略模式:是一种行为设计模式,它定义一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式通过把使用算法的责任和算法的实现分割开来,委派给不同的对象管理,来解决在有多种算法相似的情况下,使用“if...else”所带来的复杂和难以维护的问题。下面说一下具体场景,当你的系统要对接多个系统的时候,想要根据不同的入参来调用不同的实现方法,并且想要支持可以继续集成系统的前提下对源代码的业务逻辑不改变的前提下,可以随意的进行多系统的接入。而且要在系统中可配置随时切换接入系统。

下面是一个实现的小DEMO,

首先自定义一个注解,这里用到自定义注解来对接入系统有更好的管控和规范

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited//将继承该自定义注解接口的子类也可以继承该注解(用来在代理类中获取注解)
public @interface SerService {
    String datasource() default "";  //数据来源
    String desc();                   //描述信息
}

第二步写一个接口,这里的接口是一个通用的对外接口,这里可以定义统一的入参规范和要求

具体入参有入参地址和请求id

public interface ISSynUserInfo {
    public String getServiceName();
    public String getServiceDesc();
    //通知外部系统单据扫描状态
    public JSONObject sendBill(JSONObject json, String url, String requestid);
}

 

 第三步写一个上面接口的实现类,具体的业务逻辑接入

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


@Component
@SerService(desc = "One", datasource = "One")
public class TestSynUserInfoImplOne implements ISSynUserInfo {
    private static final Logger logger = LoggerFactory.getLogger(TestSynUserInfoImplOne.class);
    @Override
    public String getServiceName() {
        return "TestSynUserInfoImplOne";
    }

    @Override
    public String getServiceDesc() {
        return "策略模式实现类1";
    }

    @Override
    public JSONObject sendBill(JSONObject json, String url, String requestid) {
        JSONObject json1 =new JSONObject();
        json1.put("one","实现类1");
        return json1;
    }
}

 实现类2

 


import com.alibaba.fastjson.JSONObject;
import com.service.ISSynUserInfo;
import com.service.SerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


@Component
@SerService(desc = "TWO", datasource = "TWO")
public class TestSynUserInfoImplTwo implements ISSynUserInfo {
    private static final Logger logger = LoggerFactory.getLogger(TestSynUserInfoImplTwo.class);

    @Override
    public String getServiceName() {
        return "TestSynUserInfoImplTWO";
    }

    @Override
    public String getServiceDesc() {
        return "策略模式实现类2";
    }

    @Override
    public JSONObject sendBill(JSONObject json, String url, String requestid) {
        JSONObject returnjson = new JSONObject();
        returnjson.put("two","策略模式实现类2");
        return returnjson;
    }
}

下面是策略模式的重点

package com.transfer;

import com.alibaba.fastjson.JSON;
import com.service.ISSynUserInfo;
import com.service.SerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Map;
@Component
public class UtilsInterciceTool {
    private static final Logger logger = LoggerFactory.getLogger(UtilsInterciceTool.class);
    /*
    * 全局bean工厂
    * */
    @Autowired
    private ApplicationContext applicationContext;
    public ISSynUserInfo findSynStatus(String datasource) throws Exception{
        ISSynUserInfo reresult = null;
//通过上下文将自定义的注解通过具体引用获取到
        Map<String, Object> beansWithAnnotationMap = applicationContext.getBeansWithAnnotation(SerService.class);

        findModel:
        if(beansWithAnnotationMap!=null && beansWithAnnotationMap.size()>0) {
            for (String item : beansWithAnnotationMap.keySet()) {
                ISSynUserInfo model = (ISSynUserInfo)beansWithAnnotationMap.get(item);
                Annotation[] annotations = model.getClass().getAnnotations();
                logger.info("查到的注解是:"+JSON.toJSONString(annotations));
                for (Annotation annotation : annotations) {
                    if (annotation.annotationType() == SerService.class) {
                        SerService mm = (SerService) annotation;
                        String[] mms = mm.datasource().split(",");
                        for(String sour:mms){
                            if(datasource.equals(sour)){
                                reresult = model;
                                break findModel;
                            }
                        }

                    }
                }
            }
        }
        return reresult;
    }

}

 下面是具体的业务实现

package com.serviceimpl;


import com.service.ISSynUserInfo;
import com.transfer.UtilsInterciceTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import org.springframework.transaction.annotation.Transactional;


@Service
public class SendBillService {
    private static final Logger logger = LoggerFactory.getLogger(SendBillService.class);
	@Autowired
	private UtilsInterciceTool utilsInterciceTool;



	@Transactional
	public JSONObject sendBill(JSONObject json, String requestid) throws Exception{
		JSONObject jsonObject =new JSONObject();
			String client = json.getString("datasource");
			String interurlinfo = "";
			ISSynUserInfo model = utilsInterciceTool.findSynStatus(client);
			if (model != null) {
			    jsonObject = model.sendBill(json, interurlinfo, requestid);

			} 
	     return jsonObject;
	}

}

好了接下来就可以写一个接口试着调用一下了

 

package com.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.pojo.User;
import com.service.UserService;
import com.serviceimpl.SendBillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
    public class SynsendbilllController {
        private static final Logger log = LoggerFactory.getLogger(SynsendbilllController.class);
    @Autowired
    private SendBillService sendBillService;
    @GetMapping("/query/syn")
    public JSONObject query(User user) throws Exception {
        JSONObject json =new JSONObject();
        String requestId= "31211131113123123";
//        json.put("datasource","One");
        //用来模拟从数据库中查到的配置项的入参
        json.put("datasource","TWO");
        JSONObject object = sendBillService.sendBill(json, requestId);
        log.info(JSON.toJSONString(object));
        return object;
    }
}

 运行结果(当入参是json.put("datasource","TWO"))

运行结果((当入参是json.put("datasource","One")))

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐