规格模式

带与或非的规格书接口

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 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));

你可能感兴趣的:(规格模式)