在一个较为复杂的业务流程中,某些条件的满足与否决定了业务逻辑的走向,我们可以把这些条件抽离出来,使得任意个条件以某种关系进行组合,从而灵活地对业务逻辑进行定制。另外,在查询、过滤等应用场合中,我们也可以预定义多个条件,使用这些条件的组合来处理查询逻辑,而不是使用逻辑判断语句来处理,那样只会让代码变得复杂,让脑袋变大。
在Specification设计模式中,一个条件就是一个specification,多个specification通过串联的方式以某种逻辑关系形成一个组合式的specification。首先看一下整体的UML图:
下面是Specification接口的声明:
public interface Specification {
boolean isSatisfiedBy(Object params);
Specification and(Specification other);
Specification or(Specification other);
Specification not();
}
它定义了各个条件间可用的关系:与、或、非,这三个关系所对应方法的返回值都是Specification自身,目的是为了实现Specification之间的串联(chaining),从而形成一个关系表达式,后面会看到具体的用法。isSatisfiedBy就是判定方法,参数是一个Object,支持任意类型。
下面我们来看CompositSpecification的声明:
public abstract class CompositeSpecification implements Specification{
@Override
public Specification and(Specification other) {
return new AndSpecification(this, other);
}
public abstract boolean isSatisfiedBy(Object params);
@Override
public Specification not() {
return new NotSpecification(this);
}
@Override
public Specification or(Specification other) {
return new OrSpecification(this, other);
}
}
它实现了Specification接口的关系判定方法,而isSatisfiedBy则仍是抽象方法,需要派生类来具体实现。下面是三个分别实现了与、或、非关系判定的派生类的声明:
public class AndSpecification extends CompositeSpecification {
private final Specification b;
private final Specification a;
public AndSpecification(Specification a,Specification b) {
this.a = a;
this.b = b;
}
@Override
public boolean isSatisfiedBy(Object params) {
return a.isSatisfiedBy(params) && b.isSatisfiedBy(params);
}
}
public class OrSpecification extends CompositeSpecification {
private final Specification b;
private final Specification a;
public OrSpecification(Specification a, Specification b) {
this.a = a;
this.b = b;
}
@Override
public boolean isSatisfiedBy(Object params) {
return a.isSatisfiedBy(params) || b.isSatisfiedBy(params);
}
}
public class NotSpecification extends CompositeSpecification {
private final Specification a;
public NotSpecification(Specification a) {
this.a = a;
}
@Override
public boolean isSatisfiedBy(Object params) {
return !a.isSatisfiedBy(params);
}
}
这些类就构成了Specification模式的核心部分,下面我们来看一个例子:
先定义一个男人:
public class Men {
public String name; // 姓名
public boolean married; // 是否已婚
public int cars; // 拥有车的数量
public int houses; // 拥有房子的数量
public Men(String name,int cars, int houses, boolean married) {
this.name = name;
this.cars = cars;
this.houses = houses;
this.married = married;
}
}
然后定义选男人的几个条件:
// 有车
public class HasCarsSpecification extends CompositeSpecification {
@Override
public boolean isSatisfiedBy(Object params) {
Men m = (Men)params;
return m.cars > 0;
}
}
// 有房
public class HasHousesSpecification extends CompositeSpecification {
@Override
public boolean isSatisfiedBy(Object params) {
Men m = (Men)params;
return m.houses > 0;
}
}
// 已婚
public class MarriedSpecification extends CompositeSpecification {
@Override
public boolean isSatisfiedBy(Object params) {
Men m = (Men)params;
return m.married;
}
}
好,下面有位女嘉宾开始选它心目中的男人了:
Men[] candidates = {
new Men("李精英", 1, 1, false),
new Men("王老五", 5, 3, true),
new Men("赵白领", 0, 1, false),
new Men("West_Link", 0, 0, false)
};
HasHousesSpecification hasHouse = new HasHousesSpecification();
HasCarsSpecification hasCar = new HasCarsSpecification();
MarriedSpecification married = new MarriedSpecification();
Specification spec = hasHouse.and(hasCar).and(married.not());
for (Men men : candidates) {
if(spec.isSatisfiedBy(men))
System.out.println(men.name);
}
从Specification spec = hasHouse.and(hasCar).and(married.not())这行代码可以看出这位女嘉宾选择了有车
并且有房的未婚男子,所以打印结果为:李精英。
经过多轮选择,West_Link始终没有被选上!
分享到:
相关推荐
GoF的经典著作设计模式(Design Pattern)
GOF 设计模式 中文 高清 经典书籍 值得拥有 带目录 适合进阶
自己去实现GoF的23中模式时候的知其然不知其所以然,并且有一天在自己设计的系统种由于设计的原因让自己苦不堪言,突然悟到了设计模 第 2 页 共 105 页 k_eckel 设计模式精解-GoF 23 种设计模式解析附 C++实现源码 ...
学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料学习设计模式好的资料
而思想则是指导行为的一切,理解和掌握了设计模式,并不是说记住了23种(或更多)设计场景和解决策略(实际上这也是很重要的一笔财富),实际接受的是一种思想的熏陶和洗礼,等这种思想融入到了你的思想中后,...
GOF设计模式中英文+设计模式精解中英文,一共四个文档,高清版
以文本和思维导图的方式简明扼要的介绍了GoF的23个经典设计模式,可当成学习设计模式的一个小手册,偶尔看一下,说不定会对大师的思想精髓有新的领悟。
设计模式精解- GoF 23种设计模式解析附C++实现源码 懂了设计模式,你就懂了面向对象分析和设计(OOA/D)的精要。反之好像也可能成立。道可道,非常道。道不远人,设计模式亦然如此。 一直想把自己的学习经验以及在...
设计模式精解-GoF-23种设计模式解析--附C++源代码,帮助理解!
著名的EJB领域顶尖的专家Richard Monson-Haefel在其个人网站:www.EJBNow.com中极力推荐的GoF的《设计模式》,原文如下: Design Patterns Most developers claim to experience an epiphany reading this book....
GOF23种经典设计模式中文版 学习设计模式的必备书籍
设计模式精解-GoF23种设计模式解析(附C++实现源码)
GOF的23个设计模式
摘要:电子书籍,C#教程,设计模式 设计模式:基于C#的工程化实现及扩展 pdf全书下载,本书作者以C#重新实现了GOF的模式,同时加入了新近的设计想法,如SOA与Web Services.....等,同时还有相对于其他设计模式而言较新...
GOF是设计模式的经典名著Design Patterns: Elements of Reusable Object-Oriented Software(中译本名为《设计模式——可复用面向对象软件的基础》)的四位作者,他们分为是:Elich Gamma、Richard Helm、Ralph ...
23种设计模式UML类图,以及相应的源码,文档,自己找过的,查阅过的网上的资料
设计模式精解-GoF 23种设计模式解析.pdf
Gof-23种设计模式,观察者,适配器,单例,工厂模式
GOF设计模式(中英文双语) GOF设计模式(中英文双语) GOF设计模式(中英文双语)