规约模式(Specification Pattern),简单来说就是就是约束条件,例如从数据库中获取到满足约束条件的数据(where
条件之后即为约束条件):
1 | select * from `book` where `name` like `%java%` and `price` < 50; |
如果我们要用java
实现类似约束,可能会想到:
1 | for (Book book : books) { |
规约一般实现
1 | public interface Specification<T> { |
上面即为规约模式的一般实现,可以看到在接口Specification
中定义了4个方法:1
2
3
4isSatisfiedBy():是否满足指定条件
and():条件与
or():条件或
not():条件非
与,或,非3个条件的组合已经基本可以满足日常查询条件
创建约束条件
假设我们有如下Book
对象:
1 | public class Book { |
如果要求的单查询条件为名称包含指定关键字,价格在指定区间内,指定出版年份,我们可以创建如下对象:
1 | // 名称约束条件 |
根据这三个约束条件,我们可以组合出多种不同的约束条件,比如我们希望查询名称包含Java,价格在30~60元,在2019年出版:
1 | Specification<Book> bookSpecification = new BookNameSpecification("java") |
测试
1 | public class Main { |
总结
规约模式适用于内存过滤,不同的单约束条件可以相互组合,但是对每一种单约束都需要创建对应的约束类
参考
Martin Fowler & Eric Evans: Specifications
Specification Pattern in Java