规格模式已经是一个非常具体的应用框架了(相对于23个设计模式),大家遇到类似多个对象中筛选查找,或者“业务规则不适于放在任何已有实体或值对象中,而且规则的变化和组合会掩盖那些领域对象的基本含义”,或者是想自己编写一个类似LINQ的语言工具的时候就可以照搬这部分代码,只要实现自己的逻辑规格书即可。
代码:抽象规格书
public interface ISpecification {
//候选人是否满足要求
boolean isSatisfiedBy(Object candidate);
//and操作
ISpecification add(ISpecification spec);
//or操作
ISpecification or(ISpecification spec);
//not操作
ISpecification not();
}
组合规格书
public abstract class CompositeSpecification implements ISpecification {
//是否满足条件由实现类决定
public abstract boolean isSatisfiedBy(Object candidate);
@Override
public ISpecification add(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 left.isSatisfiedBy(candidate) && right.isSatisfiedBy(candidate);
}
}
或规格书
public class OrSpecification extends CompositeSpecification {
//传递两个规格书进行or操作
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 left.isSatisfiedBy(candidate) || right.isSatisfiedBy(candidate);
}
}
非规格书
public class NotSpecification extends CompositeSpecification {
//传递一个规格书进行not操作
private ISpecification specification;
public NotSpecification(ISpecification spec) {
this.specification = spec;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
return !specification.isSatisfiedBy(candidate);
}
}
用户user
public class User {
private int age;
private String name;
public User(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
年龄大于基准年龄
public class UserAgeThan extends CompositeSpecification {
private int age;
public UserAgeThan(int age) {
this.age = age;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
User user = (User) candidate;
return age < user.getAge();
}
}
姓名包含某个字符
public class UserLikeName extends CompositeSpecification {
private String like;
public UserLikeName(String like) {
this.like = like;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
User user = (User) candidate;
return user.getName().contains(like);
}
}
测试
public class Test {
public static void main(String args[]) {
List<User> list = new ArrayList<>();
for (int i = 20; i < 40; i++) {
User user = new User(i, "李" + i);
list.add(user);
}
ISpecification age = new UserAgeThan(25); //年龄大于25
ISpecification name = new UserLikeName("3"); //姓名带3
for (User user : list) {
if (age.add(name).isSatisfiedBy(user)) {
System.out.println("姓名:" + user.getName() + "----------年龄:" + user.getAge());
}
}
}
}
结果
姓名:李30----------年龄:30
姓名:李31----------年龄:31
姓名:李32----------年龄:32
姓名:李33----------年龄:33
姓名:李34----------年龄:34
姓名:李35----------年龄:35
姓名:李36----------年龄:36
姓名:李37----------年龄:37
姓名:李38----------年龄:38
姓名:李39----------年龄:39