规格模式(Specification Pattern)。

定义

组合模式+策略模式。

通用源码

规格模式非常重要,他巧妙的实现了对象筛选功能。我们来看其通用源码,首先看抽象规格书,如下所示。

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的语言工具的时候就可以照搬这部分代码,只要实现自己的逻辑规格书即可。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/83007729