帶與或非的規(guī)格書接口
interface ISpecification {
// 是否滿足條件
boolean isSatisfiedBy(Request request)
public ISpecification and(ISpecification spec);
public ISpecification or(ISpecification spec);
public ISpecification not();
}
父類不是不能依賴子類,在明確不會(huì)發(fā)生變化的場(chǎng)景里可以存在,因?yàn)橐蕾囎宇惒皇敲嫦蚪涌诰幊?,不具備擴(kuò)展性。
組合規(guī)格書類
abstract class CompositeSpecification implements ISpecification {
// 具體的命中邏輯交給子類實(shí)現(xiàn)
abstract boolean isSatisfiedBy(Request);
ISpecification and(ISpecification spec) {
// 這里依賴了子類,但是and這個(gè)邏輯如果是不會(huì)變化的,這樣固化也沒有問題
return new AndSpecification(this, spec);
}
ISpecification not() {
return new NotSpecification(this);
}
ISpecification or(ISpecification spec) {
return new OrSpecification(this, spec);
}
}
與規(guī)格書類
class AndSpecification extends CompositeSpecification {
// 這里是重點(diǎn):這個(gè)類通過依賴多個(gè)相同接口類型的其他類,作為一個(gè)合并的操作,減少了參數(shù)的個(gè)數(shù)
private ISpecification left;
private ISpecification right;
public AndSpecification(left, right) {
this.left = left;
this.right = right;
}
// 或規(guī)格書,非規(guī)格書類似,重載實(shí)現(xiàn)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;
}
}
場(chǎng)景類
ISpecification spec1 = new UserByAgeThan(25);
ISpecification spec2 = new UserByName("abc");
// 2個(gè)spec經(jīng)過and方法,返回了一個(gè)spec,滿足了findUser方法參數(shù)的個(gè)數(shù)
provider.findUser(spec.and(spec2));