定义
组合模式+策略模式。
通用源码
规格模式非常重要,他巧妙的实现了对象筛选功能。我们来看其通用源码,首先看抽象规格书,如下所示。
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的语言工具的时候就可以照搬这部分代码,只要实现自己的逻辑规格书即可。