问题引出
笔者目前在机票行业,前几天有同事聊到一个这样的问题。某个报价是否可对用户可见,不同的航司可能要求不一样,比如国航会要求时间满足一定条件,南航可能会要求日期并且仓位满足一定条件,而东航可能会要求日期或者仓位满足要求,甚至要求会更复杂,而航司也会很多,也许还会更改判定条件,那么遇到这种情况要如何处理呢?
思路
由于要保留可变性,所以需要做到配置的,而可配置的一定都是字符串,那么我们要做的就是将文字描述的逻辑关系转化为相应的代码描述。
而要实现这两点,想到了以下两点.
1. 学编译原理的时候,提到的四则运算时的中辍表达式转后辍表达式(也叫波兰式与逆波兰式)
2. 利于Guava
的com.google.common.base.Predicates
将多个com.google.common.base.Predicate
转化为一个最终的Predicate
,利用predicate.apply()
就可以判定结果是否满足。
代码
直接上代码,代码中没有直接实现判定的逻辑,在实际中可以自行实现。
支持的逻辑表达有: 与:用&表示;或:用|表示;并且支持括号
参数(或者叫判定条件有):年龄,性别,地址,学校,学科。 这个只是个举例,具体的如何判定没有实现,这个判定条件是随机写的,没有明确的意义。
一个标志接口
package com.personal;
/**
* Created by Administrator on 2017/2/23.
* 定义了一个标志接口,因为中间使用的时候,会往List中放相应的判定条件及运算符
*/
public interface Meta{
}
逻辑关系运算符
package com.personal;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
/**
* Created by Administrator on 2017/2/23.
* 定义的逻辑运算符
*/
public enum Operator implements Meta{
AND {
boolean is ( String operator ) {
return "&".equals( operator );
}
public < T > Predicate< T > combine ( Predicate< T > predicate1, Predicate< T > predicate2 ) {
return Predicates.and(predicate1,predicate2);
}
},
OR {
boolean is ( String operator ) {
return "|".equals( operator );
}
public < T > Predicate< T > combine ( Predicate< T > predicate1, Predicate< T > predicate2 ) {
return Predicates.or(predicate1,predicate2);
}
},
LEFT_BRACKET {
boolean is ( String operator ) {
return "(".equals( operator );
}
},
RIGHT_BRACKET {
boolean is ( String operator ) {
return ")".equals( operator );
}
};