• 代码优化~隔离接口实现类


    业务背景描述

    一个业务需求需要多人协助的时候,在一个类中定义N个接口,一个实现类多人协作开发,存在以下的问题

    1. 冲突严重
    2. 单类代码量巨大,不容易维护

    你可能会想, 定义N个接口,N个实现类,多个人开发这样就不会有冲突
    曾经也这样试过,但是后期非常不好维护,明明是同一个业务,只因开发的人不一样。定义成多个接口和实现类,这样再找问题,找方法的时候非常不友好。因此这是不被采用的。
    目标: 一个接口定义类,有个接口实现类,每个接口实现类只实现自己的方法,不用实现全部。

    接口适配器模式 + @Delegate 注解

    接口适配器模式:写一个实现适配类去继承该接口,但是没有具体的实现或者空实现,其他人的类 继承该接口适配类,重写自己需要写的方法。
    @Delegate 为该类实现空实现方法

    case1

    1、 定义接口类

    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:34
     **/
    public interface DoService {
    	/**
    	 * 说明
    	 * @param eventName
    	 */
    	void speak(String eventName);
    
    	/**
    	 * 跑步
    	 * @param eventName
    	 */
    	void running(String eventName);
    
    	/**
    	 * 睡觉
    	 * @param eventName
    	 */
    	void sleeping(String eventName);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    接口适配器类实现

    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:37
     **/
    @Service
    public abstract class DoServiceAdapter implements DoService {
    	@Delegate
    	private DoService nullService;
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    @Delegate 会自动生成默认空实现方法

    具体实现类

    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:51
     **/
    @Service(value = "running")
    public class RunningDoServiceImpl extends DoServiceAdapter {
    	@Override
    	public void running(String eventName) {
    		System.out.println("====== running =======");
    		System.out.println(eventName);
    		System.out.println("====== running =======");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:40
     **/
    @Service(value = "sleep")
    public class SleepDoServiceImpl extends DoServiceAdapter {
    
    	@Override
    	public void sleeping(String eventName) {
    		System.out.println("====== sleep =======");
    		System.out.println(eventName);
    		System.out.println("====== sleep =======");
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:52
     **/
    @Service(value = "speak")
    public class SpeakDoServiceImpl extends DoServiceAdapter{
    	@Override
    	public void speak(String eventName) {
    		System.out.println("====== speak =======");
    		System.out.println(eventName);
    		System.out.println("====== speak =======");
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试类

    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:54
     **/
    @Controller
    @RequestMapping("/do")
    public class DoController {
    	@Resource(name = "running")
    	private DoService runningDoService;
    
    	@Resource(name = "sleep")
    	private DoService sleepDoService;
    
    	@Resource(name = "speak")
    	private DoService speakDoService;
    
    	@Autowired
    	private DoVersionFactory doVersionFactory;
    
    
    	@RequestMapping("/speak")
    	@ResponseBody
    	public String speak() {
    		String eventName = "speak";
    		speakDoService.speak(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.speaking);
    		instance.speak(eventName);
    		return eventName;
    	}
    
    	@RequestMapping("/running")
    	@ResponseBody
    	public String running() {
    		String eventName = "running";
    		runningDoService.running(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.running);
    		instance.running(eventName);
    		return eventName;
    	}
    
    	@RequestMapping("/sleeping")
    	@ResponseBody
    	public String sleeping() {
    		String eventName = "sleeping";
    		sleepDoService.sleeping(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.sleeping);
    		instance.sleeping(eventName);
    		return eventName;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    优点: 实现类分离,减少冲突
    缺点: 需要了解每个方法的具体重写类,指定重写的类使用

    接口适配器模式+工厂管理类处理

    工厂模式:由一个工厂类来管理接口的所有实现,调度
    上述接口适配器模式,存在一个问题,每次有新的实现都需要@Autowired注入,然后使用,这样就很麻烦,因此呢, 需要一个统一的工厂类来管理所有的实现类

    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:34
     **/
    @Service
    public abstract class DoServiceVersion2 {
    	@Delegate
    	private DoService nullService;
    
    	protected abstract DoEnum queryType();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    工厂类

    package com.dgut.edu.cn.springbootxiaozheng.service.impl;
    
    import com.dgut.edu.cn.springbootxiaozheng.enums.DoEnum;
    import com.google.common.collect.Maps;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.PostConstruct;
    import java.util.Map;
    
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-14 10:55
     **/
    @Service
    public class DoVersionFactory {
    
    	@Autowired
    	private ApplicationContext context;
    
    	Map<DoEnum, DoServiceVersion2> map;
    
    	@PostConstruct
    	private void init() {
    		map = Maps.newHashMap();
    		Map<String, DoServiceVersion2> beansOfType = context.getBeansOfType(DoServiceVersion2.class);
    		for(DoServiceVersion2 doServiceVersion2 : beansOfType.values()) {
    			map.put(doServiceVersion2.queryType(), doServiceVersion2);
    		}
    	}
    
    	public DoServiceVersion2 getInstance(DoEnum queryType){
    		return map.get(queryType);
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    具体实现类

    package com.dgut.edu.cn.springbootxiaozheng.service.impl;
    
    import com.dgut.edu.cn.springbootxiaozheng.enums.DoEnum;
    import org.springframework.stereotype.Service;
    
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-14 10:52
     **/
    @Service
    public class RunningVersion2ServiceImpl extends DoServiceVersion2 {
    
    
    	@Override
    	public void running(String eventName) {
    		System.out.println("====== running =======");
    		System.out.println(eventName);
    		System.out.println("====== running =======");
    	}
    
    	@Override
    	protected DoEnum queryType() {
    		return DoEnum.running;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    package com.dgut.edu.cn.springbootxiaozheng.service.impl;
    
    import com.dgut.edu.cn.springbootxiaozheng.enums.DoEnum;
    import org.springframework.stereotype.Service;
    
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-14 10:52
     **/
    @Service
    public class SleepVersion2ServiceImpl extends DoServiceVersion2 {
    
    
    	@Override
    	public void sleeping(String eventName) {
    		System.out.println("====== sleep =======");
    		System.out.println(eventName);
    		System.out.println("====== sleep =======");
    	}
    
    
    	@Override
    	protected DoEnum queryType() {
    		return DoEnum.sleeping;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    package com.dgut.edu.cn.springbootxiaozheng.service.impl;
    
    import com.dgut.edu.cn.springbootxiaozheng.enums.DoEnum;
    import org.springframework.stereotype.Service;
    
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-14 10:52
     **/
    @Service
    public class SpeakVersion2ServiceImpl extends DoServiceVersion2 {
    
    
    	@Override
    	public void speak(String eventName) {
    		System.out.println("====== speak =======");
    		System.out.println(eventName);
    		System.out.println("====== speak =======");
    	}
    
    	@Override
    	protected DoEnum queryType() {
    		return DoEnum.speaking;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    测试

    package com.dgut.edu.cn.springbootxiaozheng.controller;
    
    import com.dgut.edu.cn.springbootxiaozheng.enums.DoEnum;
    import com.dgut.edu.cn.springbootxiaozheng.service.DoService;
    import com.dgut.edu.cn.springbootxiaozheng.service.impl.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.annotation.Resource;
    
    /**
     * @description:
     * @author: hongbin.zheng
     * @create: 2022-09-13 18:54
     **/
    @Controller
    @RequestMapping("/do")
    public class DoController {
    	@Resource(name = "running")
    	private DoService runningDoService;
    
    	@Resource(name = "sleep")
    	private DoService sleepDoService;
    
    	@Resource(name = "speak")
    	private DoService speakDoService;
    
    	@Autowired
    	private DoVersionFactory doVersionFactory;
    
    
    	@RequestMapping("/speak")
    	@ResponseBody
    	public String speak() {
    		String eventName = "speak";
    		speakDoService.speak(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.speaking);
    		instance.speak(eventName);
    		return eventName;
    	}
    
    	@RequestMapping("/running")
    	@ResponseBody
    	public String running() {
    		String eventName = "running";
    		runningDoService.running(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.running);
    		instance.running(eventName);
    		return eventName;
    	}
    
    	@RequestMapping("/sleeping")
    	@ResponseBody
    	public String sleeping() {
    		String eventName = "sleeping";
    		sleepDoService.sleeping(eventName);
    		DoServiceVersion2 instance = doVersionFactory.getInstance(DoEnum.sleeping);
    		instance.sleeping(eventName);
    		return eventName;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在这里插入图片描述

    总结

    知道的越多,不知道的越多,希望对你有帮助! \color{red}知道的越多,不知道的越多,希望对你有帮助! 知道的越多,不知道的越多,希望对你有帮助!

  • 相关阅读:
    [VSCode] 替换掉/去掉空行
    Verilog disable语句
    Qt图形视图、动画框架
    操作系统 线程死锁
    C#实现TFTP客户端
    【机器学习】树模型预剪枝和后剪枝
    2022.07.19 随机数字python
    【考研】操作系统——处理机调度算法1
    GC回收算法
    2022 需求工程综合论述题【太原理工大学】
  • 原文地址:https://blog.csdn.net/xiaozhegaa/article/details/126849844