规格模式
- 描述
- 组件
- 使用
描述
规格模式并不在传统的23设计模式中,属于后面扩展的设计模式。
简单描述就是对一批数据进行多条件(包括逻辑组合、有点装饰器的感觉,可以不断套娃)匹配。
组件
- 实体
package dp.spec;
/**
* TODO
*
* @author kal
* @version 1.0.0
* @date 2025/5/25 23:13
*/
public class User {
private Long id;
private String name;
private Integer age;
private String gender;
public User(Long id, String name, Integer age, String gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
public static class UserBuilder {
private Long id;
private String name;
private Integer age;
private String gender;
public static UserBuilder builder() {
return new UserBuilder();
}
public UserBuilder id(Long id) {
this.id = id;
return this;
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(Integer age) {
this.age = age;
return this;
}
public UserBuilder gender(String gender) {
this.gender = gender;
return this;
}
public User build() {
return new User(this.id, this.name, this.age, this.gender);
}
}
}
- 通用匹配接口
public interface IUserSelector {
List<User> query(IUserSpec spec);
}
- 匹配接口实现
public class UserSelector implements IUserSelector {
private final List<User> userList;
public UserSelector(List<User> userList) {
this.userList = userList;
}
@Override
public List<User> query(IUserSpec spec) {
List<User> result = new ArrayList<>();
userList.forEach(user -> {
if (spec.match(user)) {
result.add(user);
}
});
return result;
}
}
- 规格接口
public interface IUserSpec {
boolean match(User user);
IUserSpec and(IUserSpec userSpec);
IUserSpec or(IUserSpec userSpec);
IUserSpec not();
}
- 实现组合逻辑的抽象规格类
public abstract class CompositeSpec implements IUserSpec {
@Override
public IUserSpec and(IUserSpec userSpec) {
return new AndSpec(this, userSpec);
}
@Override
public IUserSpec or(IUserSpec userSpec) {
return new OrSpec(this, userSpec);
}
@Override
public IUserSpec not() {
return new NotSpec(this);
}
}
- 组合规格
public class AndSpec extends CompositeSpec {
private final IUserSpec first;
private final IUserSpec second;
public AndSpec(IUserSpec first, IUserSpec second) {
this.first = first;
this.second = second;
}
@Override
public boolean match(User user) {
return first.match(user) && second.match(user);
}
}
public class OrSpec extends CompositeSpec {
private final IUserSpec first;
private final IUserSpec second;
public OrSpec(IUserSpec first, IUserSpec second) {
this.first = first;
this.second = second;
}
@Override
public boolean match(User user) {
return first.match(user) || second.match(user);
}
}
public class NotSpec extends CompositeSpec {
private final IUserSpec first;
public NotSpec(IUserSpec first) {
this.first = first;
}
@Override
public boolean match(User user) {
return !first.match(user);
}
}
- 具体业务规格
public class GenderEqSpec extends CompositeSpec {
private final String gender;
public GenderEqSpec(String gender) {
this.gender = gender;
}
@Override
public boolean match(User user) {
return Objects.equals(user.getGender(), gender);
}
}
public class NameEqSpec extends CompositeSpec {
private final String name;
public NameEqSpec(String name) {
this.name = name;
}
@Override
public boolean match(User user) {
return Objects.equals(user.getName(), name);
}
}
使用
public class Sample {
public static void main(String[] args) {
List<User> dataList = new ArrayList<>();
dataList.add(User.UserBuilder.builder()
.id(1L)
.name("张三")
.age(10)
.gender("男")
.build());
dataList.add(User.UserBuilder.builder()
.id(2L)
.name("李四")
.age(20)
.gender("女")
.build());
dataList.add(User.UserBuilder.builder()
.id(3L)
.name("王五")
.age(30)
.gender("女")
.build());
IUserSelector selector = new UserSelector(dataList);
// 两个基本规格
IUserSpec nameSpe = new NameEqSpec("张三");
IUserSpec genderEqSpec = new GenderEqSpec("女");
// 组合规格
IUserSpec spec = nameSpe.and(genderEqSpec);
List<User> result = selector.query(spec);
System.out.println(result);
}
}