带与或非的规格书接口
interface ISpecification {
// 是否满足条件
boolean isSatisfiedBy(Request request)
public ISpecification and(ISpecification spec);
public ISpecification or(ISpecification spec);
public ISpecification not();
}
父类不是不能依赖子类,在明确不会发生变化的场景里可以存在,因为依赖子类不是面向接口编程,不具备扩展性。
组合规格书类
abstract class CompositeSpecification implements ISpecification {
// 具体的命中逻辑交给子类实现
abstract boolean isSatisfiedBy(Request);
ISpecification and(ISpecification spec) {
// 这里依赖了子类,但是and这个逻辑如果是不会变化的,这样固化也没有问题
return new AndSpecification(this, spec);
}
ISpecification not() {
return new NotSpecification(this);
}
ISpecification or(ISpecification spec) {
return new OrSpecification(this, spec);
}
}
与规格书类
class AndSpecification extends CompositeSpecification {
// 这里是重点:这个类通过依赖多个相同接口类型的其他类,作为一个合并的操作,减少了参数的个数
private ISpecification left;
private ISpecification right;
public AndSpecification(left, right) {
this.left = left;
this.right = right;
}
// 或规格书,非规格书类似,重载实现isSatisfiedBy
@Override
public boolean isSatisfiedBy(request) {
return left.isSatisfiedBy(request) && right.isSatisfiedBy(request);
}
}
用户操作接口
public interface IProvider {
public List<Result> findUser(ISpecification spec);
}
用户操作
public class Provider implements IProvider {
public Result findUser(ISpecification spec) {
for(Request r : requests) {
if (spec.isSatisfiedBy(r)) {
result.add(...)
}
}
return result;
}
}
场景类
ISpecification spec1 = new UserByAgeThan(25);
ISpecification spec2 = new UserByName("abc");
// 2个spec经过and方法,返回了一个spec,满足了findUser方法参数的个数
provider.findUser(spec.and(spec2));