規格模式(Specification Pattern)。
阿新 • • 發佈:2018-11-08
定義
組合模式+策略模式。
通用原始碼
規格模式非常重要,他巧妙的實現了物件篩選功能。我們來看其通用原始碼,首先看抽象規格書,如下所示。
public interface ISpecification { /** * 候選者是否滿足需求 * * @param candidate * @return */ boolean isSatisfiedBy(Object candidate); /** * and操作 * * @param spec * @return */ ISpecification and(ISpecification spec); /** * or操作 * * @param spec * @return */ ISpecification or(ISpecification spec); /** * not操作 * * @return */ ISpecification not(); }
組合規格書實現與或非的演算法,如下所示。
public abstract class CompositeSpecification implements ISpecification { @Override public ISpecification and(ISpecification spec) { return new AndSpecification(this, spec); } @Override public ISpecification or(ISpecification spec) { return new OrSpecification(this, spec); } @Override public ISpecification not() { return new NotSpecification(this); } }
與或非規格書程式碼分別如下所示。
public class AndSpecification extends CompositeSpecification { // 傳遞兩個規格書進行and操作 private ISpecification left; private ISpecification right; public AndSpecification(ISpecification left, ISpecification right) { this.left = left; this.right = right; } @Override public boolean isSatisfiedBy(Object candidate) { return this.left.isSatisfiedBy(candidate) && this.right.isSatisfiedBy(candidate); } } public class OrSpecification extends CompositeSpecification { // 左右兩個規格書 private ISpecification left; private ISpecification right; public OrSpecification(ISpecification left, ISpecification right) { this.left = left; this.right = right; } @Override public boolean isSatisfiedBy(Object candidate) { return this.left.isSatisfiedBy(candidate) || this.right.isSatisfiedBy(candidate); } } public class NotSpecification extends CompositeSpecification { // 傳遞一個規格書 private ISpecification spec; public NotSpecification(ISpecification spec) { this.spec = spec; } @Override public boolean isSatisfiedBy(Object candidate) { return this.isSatisfiedBy(spec); } }
以上一個介面、一個抽象類、3個實現類只要在適用規格模式的地方都完全相同,不用做任何的修改,大家閉著眼chao6就成,要修改的是下面的規格書——業務規格書,如下所示。
public class BizSpecification extends CompositeSpecification {
// 基準物件
@SuppressWarnings("unused")
private Object obj;
public BizSpecification(Object obj) {
this.obj = obj;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
// 根據基準物件和候選物件,進行業務判斷,返回boolean
return false;
}
}
然後就是看怎麼使用了,場景類如下所示。
public class Client {
public static void main(String[] args) {
// 待分析的物件
ArrayList<Object> list = new ArrayList<Object>();
// 定義兩個業務規格書
ISpecification spec1 = new BizSpecification(new Object());
ISpecification spec2 = new BizSpecification(new Object());
// 規則的呼叫
for (Object obj : list) {
if (spec1.and(spec2).isSatisfiedBy(obj)) { // and操作
System.out.println(obj);
}
}
}
}
規格模式已經是一個非常具體的應用框架了(相對於23個設計模式),大家遇到類似多個物件中篩選查詢,或者業務規則不適於放在任何已有實體或值物件中,而且規則的變化和組合會掩蓋那些領域物件的基本含義,或者是想自己編寫一個類似LINQ的語言工具的時候就可以照搬這部分程式碼,只要實現自己的邏輯規格書即可。