设计模式简述(二十)规格模式
规格模式
- 描述
- 组件
- 使用
描述
规格模式并不在传统的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;}@Overridepublic 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;}@Overridepublic 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 {@Overridepublic IUserSpec and(IUserSpec userSpec) {return new AndSpec(this, userSpec);}@Overridepublic IUserSpec or(IUserSpec userSpec) {return new OrSpec(this, userSpec);}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic boolean match(User user) {return !first.match(user);}
}
- 具体业务规格
public class GenderEqSpec extends CompositeSpec {private final String gender;public GenderEqSpec(String gender) {this.gender = gender;}@Overridepublic 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;}@Overridepublic 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);}
}