背景:

现在项目中很多场景下都有多个类型的数据进行分类,比如:后台操作日志中的日志类型,资金账户流转的类型等等都可以用到设计模式,从而省略了多个重复的操作代码步骤,这里可以把一些公用的代码提取出来

这里需要写一个接口用来定义一个标准,其他实现类均使用这个标准来写业务代码,本篇代码以记录操作日志来作为示例:

首先定义一个日志的bean类,所有的操作都是对该bean进行赋值操作

import lombok.Data; 
import java.time.LocalDateTime; 

@Data
public class Log {

    private String userName;
    private LogEnum logType;
    private String logContent;
    private Long userId;
    private LocalDateTime createTime;
}

然后定义一个处理接口,其他子类均实现该接口并做业务代码的操作

/**
 * @author choviwu
 */
public interface DealAction { 
    /**
     * 业务代码处理类  用来对日志的
     */
    void deal(Long userId,String userName,String content);
}

由于Log内的createTime是公用变量(实际可能还会有更多)

接下来定义一个抽象类,

用来对日志的结构进行抽象化

import lombok.Data;
import java.time.LocalDateTime;
@Data
public abstract class AbstractAction implements DealAction {
    protected Log log;

    /**
     * 初始化公共变量  比如时间等等,根据业务来
     * @param logType
     */
    public AbstractAction(LogEnum logType){
	//初始化公用变量
        log = new Log();
        log.setCreateTime(LocalDateTime.now());
        log.setLogType(logType);
    }
	//抽象方法,用来对不同的业务进行不同的
    @Override
    public abstract void deal(Long userId,String userName,String content);
}
//类型1  实际日志标记类,不同的类型定义为不同的类
public class TypeDealAction extends AbstractAction {

    public TypeDealAction() {
	  //类型的标识  比如 1 2 3 4  
        super(LogEnum.TYPE1);
    } 
    @Override
    public void deal(Long userId,String userName,String content) {
        log.setLogContent("["+userName+">>>>>>+"+content+"]");
        log.setUserId(userId);
        log.setUserName(userName);
    }
}

最后,如果是在spring中操作,再定义一个单例的bean,用来对日志进行插入操作:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import top.choviwu.garbage.sort.strategy.action.AbstractAction;
import top.choviwu.garbage.sort.strategy.action.DealAction;
import top.choviwu.garbage.sort.strategy.action.Log;

@Slf4j
@Component
public class DealModule { 
	//伪代码,插入日志
    private  int insert(Log log1){
        log.info("log success {}",log1.toString());
        return 1;
    }
	//实际执行deal方法
    public void deal(DealAction action){
        AbstractAction abstractAction = (AbstractAction) action;
        Assert.isTrue(insert(abstractAction.getLog())>0,"insert_error");

    }
}

这样做的好处是省略了许多冗余的代码,将真正公用重复的代码封装到AbstractAction,然后不同的类型定义为不同的类,真正

  • 实现业务记录的代码隔离,如果对于实时性不高的场景可以用线程池来进行操作,封装好的线程池demo参见**垃圾分类API**。

测试

执行main方法:

public static void main(String[] args) {
        DealAction dealAction = new TypeDealAction();
        dealAction.deal(123L,"奕仁","购买了《码出高效》");
        IStrategy iStrategy = new LogStrategyService();
        iStrategy.handler(dealAction);
    }

打印日志:

og success Log(userName=奕仁, logType=TYPE1, logContent=[奕仁>>>>>>+购买了《码出高效》], userId=123, createTime=2019-08-25T20:59:17.430)

代码 branch --> test分支。