zoukankan      html  css  js  c++  java
  • 1多实现接口管理

    1、背景

    在实际的项目开发过程中,经常会遇到同一个业务操作不同场景时的不同业务逻辑,这个时候为了使系统拥有更高的可扩展性,可维护性,基于此背景开发了这套框架。
    1、使用ServiceManager统一管理接口实例
    2、使用ExecuteService统一接口实现,单一职责
    3、可选AbstractExecuteServiceTemplate,使用它实现接口逻辑模板化,模板模式
    4、可选ExecuteCommonService,接口实例通过聚合ExecuteCommonService达到代码复用的目的。合成复用原则。
    

    1.1、以前

        @Autowired
        private AService aService;
        @Autowired
        private BService bService;
        @Autowired
        private CService cService;
        @Autowired
        private DService dService;
    
        @Test
        public void testOld() {
            // 以往我们的多场景实现可能是这样
            TestReq req = new TestReq();
            TestRsp rsp = null;
            if (场景A) {
                rsp = aService.execute(req);
            }
    
            if (场景B) {
                rsp = bService.execute(req);
            }
    
            if (场景C) {
                rsp = cService.execute(req);
            }
    
            if (场景D) {
                rsp = dService.execute(req);
            }
    
        }
    

    1.2、现在

            TestReq req = new TestReq();
            ExecuteService<TestReq, TestRsp> serviceA = ServiceManager.getService(ServiceEnum.SERVICE_A, ServiceTypeEnum.TEST_SERVICE_A);
            TestRsp rspA = serviceA.execute(req);
    

    2、类图

    image

    核心接口为:ExecuteService,提供业务执行的入口;
    接口实例管理器:ServiceManager,提供本地接口实例管理;
    提供两种实现方式:
    1、绿色标识为简单模式,适合接口逻辑比较独立,没有耦合的情况。
    2、蓝色标识为复杂模式,ExecuteServiceTemplate将ExecuteService的execute方法模板化,规范ExecuteService实现。
    额外提供一种代码复用的方式:
    通过使用ExecuteCommonService将共用代码进行复用,然后聚合到ExecuteService实现中。
    

    3、时序图

    image

    4、实现

    4.1、鱼骨图

    image

    framework核心包为框架核心,为业务端提供规范与平台。
    implement为业务端运用框架需要实现的类。
    client为实际调用客户端,这里展示的为测试类。
    

    4.2、framework

    4.2.1、ExecuteService

    package com.guo.core.framework.template;
    
    import org.springframework.beans.factory.InitializingBean;
    
    public interface ExecuteService<Req,Rsp> extends InitializingBean {
    
        Rsp execute(Req req);
    
    }
    

    4.2.2、ServiceManager

    package com.guo.core.framework.template;
    
    import lombok.extern.slf4j.Slf4j;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Slf4j
    public class ServiceManager {
    
        private static final Map<String, Map<String,ExecuteService<?,?>>> serviceMap = new HashMap<>();
    
        public static void registerService(BizService service, ServiceType serviceType, ExecuteService<?,?> serviceImpl) {
            log.info("服务[{}.{}]注册", service.getCode(),serviceType.getCode());
            if (!serviceMap.containsKey(service.getCode())) {
                Map<String,ExecuteService<?,?>> serviceTypeMap = new HashMap<>();
                serviceTypeMap.putIfAbsent(serviceType.getCode(), serviceImpl);
                serviceMap.putIfAbsent(service.getCode(), serviceTypeMap);
            }
    
            serviceMap.get(service.getCode()).putIfAbsent(serviceType.getCode(), serviceImpl);
        }
    
        public static ExecuteService getService(BizService service, ServiceType serviceType) {
            Map<String,ExecuteService<?,?>> serviceTypeMap = serviceMap.get(service.getCode());
            if (serviceTypeMap == null) {
                log.info("服务[{}]不存在", service.getCode());
                return null;
            }
            ExecuteService executeService = serviceTypeMap.get(serviceType.getCode());
            if (executeService == null) {
                log.info("服务[{}.{}]不存在", service.getCode(),serviceType.getCode());
                return null;
            }
    
            return executeService;
        }
    
    }
    

    4.2.3、Service

    package com.guo.core.framework.template;
    
    public interface BizService {
    
        String getCode();
    
    }
    

    4.2.4、ServiceType

    package com.guo.core.framework.template;
    
    public interface ServiceType {
    
        String getCode();
    
    }
    

    4.3、implement

    4.3.1、简单模式

    • 适合场景:适合业务逻辑简单或业务框架不清晰场景。

    4.3.1.1、ServiceEnum

    • 定义服务,用于服务注册管理
    package com.guo.core.framework.template;
    
    public enum ServiceEnum implements BizService {
    
        SERVICE_A("SERVICE_A"),
        SERVICE_B("SERVICE_B");
    
        private final String code;
    
        ServiceEnum(String code) {
            this.code = code;
        }
    
        @Override
        public String getCode() {
            return this.code;
        }
    
    }
    
    

    4.3.1.2、ServiceTypeEnum

    • 定义服务操作类型,用于服务注册管理。
    package com.guo.core.framework.template;
    
    public enum ServiceTypeEnum implements ServiceType {
    
        TEST_SERVICE_A("TEST_SERVICE_A"),
        TEST_SERVICE_B("TEST_SERVICE_B"),
        TEST_SERVICE_C("TEST_SERVICE_C"),
        TEST_SERVICE_D("TEST_SERVICE_D");
    
        private final String code;
    
        ServiceTypeEnum(String code) {
            this.code = code;
        }
    
        @Override
        public String getCode() {
            return this.code;
        }
    }
    
    

    4.3.1.3、TestReq

    • 定义接口请求数据结构体
    package com.guo.core.framework.template;
    
    import lombok.Data;
    
    @Data
    public class TestReq {
    
        private String name;
    
    }
    

    4.3.1.4、TestRsp

    • 定义接口响应数据结构体
    package com.guo.core.framework.template;
    
    public class TestRsp {
    }
    

    4.3.1.5、AService

    • 模拟简单模式A服务.A类型
    package com.guo.core.framework.template.simple;
    
    import com.guo.core.framework.template.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class AService extends AbstractExecuteService<TestReq, TestRsp> {
    
        @Autowired
        private ExecuteCommonService executeCommonService;
    
        @Override
        protected ServiceType getServiceType() {
            return ServiceTypeEnum.TEST_SERVICE_A;
        }
    
        @Override
        protected BizService getService() {
            return ServiceEnum.SERVICE_A;
        }
    
        @Override
        public TestRsp execute(TestReq testReq) {
            log.info("执行AService");
            return executeCommonService.commonService(testReq);
        }
    }
    

    4.3.1.5、BService

    • 模拟简单模式B服务.B类型
    package com.guo.core.framework.template.simple;
    
    import com.guo.core.framework.template.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class BService extends AbstractExecuteService<TestReq, TestRsp> {
    
        @Autowired
        private ExecuteCommonService executeCommonService;
    
        @Override
        protected ServiceType getServiceType() {
            return ServiceTypeEnum.TEST_SERVICE_B;
        }
    
        @Override
        protected BizService getService() {
            return ServiceEnum.SERVICE_B;
        }
    
        @Override
        public TestRsp execute(TestReq testReq) {
            log.info("执行BService");
            return executeCommonService.commonService(testReq);
        }
    }
    

    4.3.1.6、ExecuteCommonService

    • [可选]接口公共服务,用于代码复用
    package com.guo.core.framework.template;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class ExecuteCommonService {
    
        public TestRsp commonService(TestReq testReq) {
            log.info("执行公共服务:commonService");
            return new TestRsp();
        }
    
    }
    

    4.3.1.7、集成测试

        @Test
        public void testSimple() {
            // 简单模式
            TestReq req = new TestReq();
            ExecuteService<TestReq, TestRsp> serviceA = ServiceManager.getService(ServiceEnum.SERVICE_A, ServiceTypeEnum.TEST_SERVICE_A);
            TestRsp rspA = serviceA.execute(req);
    
            ExecuteService<TestReq, TestRsp> serviceB = ServiceManager.getService(ServiceEnum.SERVICE_B, ServiceTypeEnum.TEST_SERVICE_B);
            TestRsp rspB = serviceB.execute(req);
    
        }
    

    4.3.2、复杂模式

    • 适合场景:业务复杂且业务框架清晰。

    4.3.2.1、ServiceEnum

    • 定义服务,用于服务注册管理
    package com.guo.core.framework.template;
    
    public enum ServiceEnum implements BizService {
    
        SERVICE_A("SERVICE_A"),
        SERVICE_B("SERVICE_B");
    
        private final String code;
    
        ServiceEnum(String code) {
            this.code = code;
        }
    
        @Override
        public String getCode() {
            return this.code;
        }
    
    }
    
    

    4.3.2.2、ServiceTypeEnum

    • 定义服务操作类型,用于服务注册管理。
    package com.guo.core.framework.template;
    
    public enum ServiceTypeEnum implements ServiceType {
    
        TEST_SERVICE_A("TEST_SERVICE_A"),
        TEST_SERVICE_B("TEST_SERVICE_B"),
        TEST_SERVICE_C("TEST_SERVICE_C"),
        TEST_SERVICE_D("TEST_SERVICE_D");
    
        private final String code;
    
        ServiceTypeEnum(String code) {
            this.code = code;
        }
    
        @Override
        public String getCode() {
            return this.code;
        }
    }
    
    

    4.3.2.3、TestReq

    • 定义接口请求数据结构体
    package com.guo.core.framework.template;
    
    import lombok.Data;
    
    @Data
    public class TestReq {
    
        private String name;
    
    }
    

    4.3.2.4、TestRsp

    • 定义接口响应数据结构体
    package com.guo.core.framework.template;
    
    public class TestRsp {
    }
    

    4.3.2.5、CService

    • 模拟复杂模式A服务.C类型
    package com.guo.core.framework.template.complex;
    
    import com.guo.core.framework.template.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class CService extends ExecuteServiceTemplate {
    
        @Autowired
        private ExecuteCommonService executeCommonService;
    
        @Override
        protected ServiceType getServiceType() {
            return ServiceTypeEnum.TEST_SERVICE_C;
        }
    
        @Override
        protected BizService getService() {
            return ServiceEnum.SERVICE_A;
        }
    
        @Override
        protected void after(TestReq testReq, TestRsp testRsp) {
            log.info("执行CService.after");
        }
    
        @Override
        protected TestRsp post(TestReq testReq) {
            log.info("执行CService.post");
            return executeCommonService.commonService(testReq);
        }
    
        @Override
        protected void before(TestReq testReq) {
            log.info("执行CService.before");
        }
    }
    

    4.3.2.5、DService

    • 模拟复杂模式B服务.D类型
    package com.guo.core.framework.template.complex;
    
    import com.guo.core.framework.template.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class DService extends ExecuteServiceTemplate {
    
        @Autowired
        private ExecuteCommonService executeCommonService;
    
        @Override
        protected ServiceType getServiceType() {
            return ServiceTypeEnum.TEST_SERVICE_D;
        }
    
        @Override
        protected BizService getService() {
            return ServiceEnum.SERVICE_B;
        }
    
        @Override
        protected void after(TestReq testReq, TestRsp testRsp) {
            log.info("执行DService.after");
        }
    
        @Override
        protected TestRsp post(TestReq testReq) {
            log.info("执行DService.post");
            return executeCommonService.commonService(testReq);
        }
    
        @Override
        protected void before(TestReq testReq) {
            log.info("执行DService.before");
        }
    }
    

    4.3.2.6、ExecuteServiceTemplate

    • 业务模板,定义业务逻辑框架
    package com.guo.core.framework.template.complex;
    
    import com.guo.core.framework.template.AbstractExecuteService;
    import com.guo.core.framework.template.TestReq;
    import com.guo.core.framework.template.TestRsp;
    
    public abstract class ExecuteServiceTemplate extends AbstractExecuteService<TestReq, TestRsp> {
    
        @Override
        public TestRsp execute(TestReq testReq) {
            this.before(testReq);
            TestRsp testRsp = this.post(testReq);
            this.after(testReq, testRsp);
            return testRsp;
        }
    
        protected abstract void after(TestReq testReq, TestRsp testRsp);
    
        protected abstract TestRsp post(TestReq testReq);
    
        protected abstract void before(TestReq testReq);
    
    }
    

    4.3.2.7、ExecuteCommonService

    • [可选]接口公共服务,用于代码复用
    package com.guo.core.framework.template;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    @Slf4j
    @Service
    public class ExecuteCommonService {
    
        public TestRsp commonService(TestReq testReq) {
            log.info("执行公共服务:commonService");
            return new TestRsp();
        }
    
    }
    

    4.3.2.8、集成测试

        @Test
        public void testTemplate() {
            // 模板模式
            TestReq req = new TestReq();
            ExecuteService<TestReq, TestRsp> serviceC = ServiceManager.getService(ServiceEnum.SERVICE_A, ServiceTypeEnum.TEST_SERVICE_C);
            TestRsp rspC = serviceC.execute(req);
    
            ExecuteService<TestReq, TestRsp> serviceD = ServiceManager.getService(ServiceEnum.SERVICE_B, ServiceTypeEnum.TEST_SERVICE_D);
            TestRsp rspD = serviceD.execute(req);
    
        }
    
  • 相关阅读:
    鼠标滑动显示层
    软件过程+改进 +UML
    接口和抽象类的区别
    SQL SERVER – Difference Between EXEC and EXECUTE vs EXEC() – Use EXEC/EXECUTE for SP always
    XDocument.Parse Method (String)
    Robocopy use case
    Two Solutions to fix issue: ORDER BY items must appear in the select list if the statement contains a UNION, ...
    [转载]:SQL Server 连接字符串和身份验证
    Insert Data From One Table to Another
    volatile (C# Reference)
  • 原文地址:https://www.cnblogs.com/yun965861480/p/15727055.html
Copyright © 2011-2022 走看看