您现在的位置是:首页 >技术教程 >真实业务场景使用-门面模式(外观)设计模式网站首页技术教程

真实业务场景使用-门面模式(外观)设计模式

渣渣洒泪成长记 2024-06-17 10:31:55
简介真实业务场景使用-门面模式(外观)设计模式

1.前言

最近接到要修改的业务功能,这个业务增删改查很多功能都需要校验时间,比如:

1.失效时间不能超过自己父表的失效时间,

2.失效时间不能是当前时间

3.失效时间不能早于生效时间

类似这样的不同的判断还有很多,我就先举这三种例子,因为这是在一个管理功能,也许未来还有很多的这样的规则处理,所以需要好好的设计下。

2.设计实现

我想着对于这种校验是一种规则,而对于时间的校验就是时间校验规则,所以我们定义个接口,某某业务时间规则接口,并定义了两个方法,一个是对传过来的两个时间的校验范围,一个是对当前时间及另一个传输过来的时间校验范围,如下伪代码

public interface XxBussinessDateRule{
   /**
     传入两个时间进行校验
   */
   boolean dateScopeValidate(String dateOne,String dateTwo,MathSymbolsEnum mathSymbols);
   
   /**
     传入时间与当前时间进行校验
   */
   boolean dateScopeValidateByCurrent(String date,MathSymbolsEnum mathSymbols);
}

MathSymbolsEnum枚舉類是专门处理数学符号的,如大于(>),小于(<),小于等于(<=)等等等等,

传输这个值才能更灵活处理校验规则。

public enum MathSymbolsEnum{
   /**
      大于
   */
   GREATER_THAN,
   /**
      小于
   */
   LESS_THAN,
   /**
      小于等于
   */
   EQUAL_OR_LESS_THAN,
   /**
      大于等于
   */
   EQUAL_OR_GREATER_THAN,
   /**
      等于
   */
   EQUAL,
    /**
      不等于
   */
   NOT_EQUAL,
}

DefaultxxBussinessRule类:是xxBussinessRule的实现类,因为只有此一个实现类,所以名称里加一个Default,这个类主要是对时间的校验,需要根据枚举类的符号进行判断,如果大于就调用此类私有方法dateValidateGreaterThan,如果小于就找私有方法dateValidateLessThan,用于处理不同情况的校验。

在我原有的实现里,这里调用的是不同工具类的处理方法。伪代码呢就直接写死true,False返回,你可随意实现

@Component
public class DefaultxxBussinessDateRule implements XxBussinessDateRule {
    /**
     * 传入两个时间进行校验
     */
    @Override
    public boolean dateScopeValidate(String dateOne, String dateTwo, MathSymbolsEnum mathSymbols) {
        // 大于
        if (mathSymbols.name().equals("GREATER_THAN")) {
            return dateValidateGreaterThan(dateOne, dateTwo);
        }
        // 小于
        if (mathSymbols.name().equals("LESS_THAN")) {
            return dateValidateLessThan(dateOne, dateTwo);
        }
        return false;

    }

    /**
     * 传入时间与当前时间进行校验
     */
    @Override
    public boolean dateScopeValidateByCurrent(String date, MathSymbolsEnum mathSymbols) {
        // 小于等于
        if (mathSymbols.name().equals("EQUAL_OR_LESS_THAN")) {
            System.out.println("模拟校验:是否小于等于");
            return true;
        }
        return false;
    }

    private boolean dateValidateGreaterThan(String dateOne, String dateTwo) {
        // 模拟校验规则
        // 假如第一个时间大于第二个时间
        System.out.println("模拟校验:是否大于");
        return true;
    }

    private boolean dateValidateLessThan(String dateOne, String dateTwo) {
        // 模拟校验规则
        // 假如第一个时间小于第二个时间
        System.out.println("模拟校验:是否小于");
        return true;
    }

}

正常到这里就结束了,但是又考虑了下,未来如果这个功能又要加其他规则呢,和本次时间规则毫无关系呢,那就又需要新建接口,定义新的方法,ok没有问题,问题是如果再继续新加接口、定义方法呢,有这么多类都是这个功能下的规则,入口却是多个,业务逻辑也许并不相通,怎么办?

所以,加个类,这个类用来封装统一调用不同的入口使用,这个想法思路也叫门面模式(外观模式)。

门面模式:不想让用户调用更繁杂的方法,也不用让用户了解内部具体的实现,只要简单一调用就可实现方法即可。

新建统一门面类:XxBussnissRule,继承了基础的校验规则类(下面有讲),依赖业务时间类,并定义实现两个方法,这两个方法调用到了时间校验类里的规则,这样所有的调用方都以这个为入口,都调用到这里

@Component
public class XxBussnissRule extends BaseValidateRule{
    
    @Resourcce 
    private XxBussinessDateRule xxBussinessDateRule;

    public boolean dateScopeValidate(String dateOne,String dateTwo,MathSymbolsEnum mathSymbols){
         return xxBussinessDateRule.dateScopeValidate(dateOne,dateTwo,mathSymbols);
     }

    public boolean dateScopeValidateByCurrent(String date,MathSymbolsEnum mathSymbols){
        return xxBussinessDateRule.dateScopeValidateByCurrent(date,mathSymbols);
    }
   
}

加了这个统一的入口,调用就很方便了,未来添加别的规则,只要在这个类里添加即可。

除了这一点以外,我们可能会有些通用规则,对于入参可能会有判空、校验入参字段长度啊等等一些基础规则,那么我们需要新建类:BaseValidateRule

这样,XxBussnissRule就可以继承BaseValidateRule类,用户调用XxBussnissRule就自然有了基础规则的功能。

public class BaseValidateRule{
   // 举例...
   public boolean isLength(){
      return true;
   }
}

3.测试准备

测试使用,单元测试调用业务规则校验时间伪代码,可以看到,我们使用统一的类调用即可,外部引用则可以直接引用这一个类,未来扩展其他规则,还可以依赖这个入口。

@SpringBootTest
public class TestApi {
    @Resource
    private XxBussnissRule xxBussnissRule;
    @Test
    public void testFaced() {
        boolean dateValidate = xxBussnissRule.dateScopeValidate("2023-05-02", "20233-05-04", MathSymbolsEnum.GREATER_THAN);
        boolean dateValidateByCurrent = xxBussnissRule.dateScopeValidateByCurrent("2023-05-17", MathSymbolsEnum.LESS_THAN);
        System.out.println("两个日期校验比对模拟:"+dateValidate);
        System.out.println("与当前日期校验比对模拟:"+dateValidateByCurrent);
    }
}

执行结果,证明流程走下來了。 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。