一个策略模式的小例子,比较直观的体现出设计模式的魅力。
先看需求:一个用户表,含有 【名称、年龄 、分数】 字段。现有一个用户集合,
需求1:获取年龄大于30岁的用户都是谁
需求2:获取年龄小于30虽的用户都是谁
。。后期可能会扩展其他需求。。。
实现1(无设计模式),每扩展一个需求,只需要新增一个对应的方法即可。
//初始化用户集合
List<User> userList = Arrays.asList(
new User("张三", 25, 78D),
new User("李四", 14, 43D),
new User("王五", 36, 99D),
new User("赵六", 50, 35D),
new User("武松", 47, 85D)
);
@Test
public void test1() {
//查询年龄大于30的用户
List<User> resultList = queryAgeGt30(userList);
resultList.forEach(data -> System.out.println(data));
}
@Test
public void test2() {
//查询年龄小于30的用户
List<User> resultList = queryAgeLt30(userList);
resultList.forEach(data -> System.out.println(data));
}
/**
* 查询年龄小于30
*
* @param userList
* @return
*/
private List<User> queryAgeLt30(List<User> userList) {
List<User> resultList = new ArrayList<>();
for (User user : userList) {
if (user.getAge() < 30) {
resultList.add(user);
}
}
return resultList;
}
/**
* 查询年龄大于30
*
* @return
*/
private List<User> queryAgeGt30(List<User> userList) {
List<User> resultList = new ArrayList<>();
for (User user : userList) {
if (user.getAge() > 30) {
resultList.add(user);
}
}
return resultList;
}
细看代码,发现两个方法中 只有一处不一样,剩余的代码都一样。
这不得设计一下。咱们把两个方法合并为一个,把里面不一样的代码抽离出来,利用对象的多态 实现 不同的判断逻辑
实现2(策略模式)
步骤1:编写 用户过滤 接口,接口中只有一个行为方法,传入泛型T 返回 boolean
public interface BaseUserFilter<T> {
/**
* 判断方法
*/
boolean judge(T t);
}
步骤2:编写 接口实现,分别实现 年龄大于30和小于30的实现类
## 年龄大于30的过滤实现类
public class UserAgeGt30Filter implements BaseUserFilter<User> {
@Override
public boolean judge(User user) {
//判断年龄大于30
return user.getAge() > 30;
}
}
## 年龄小于30的过滤实现类
public class UserAgeLt30Filter implements BaseUserFilter<User>{
@Override
public boolean judge(User user) {
//判断年龄小于30
return user.getAge()<30;
}
}
最后 合并 过滤方法
/**
* 策略模式优化 , 变化的代码抽离
*
* @return
*/
private List<User> queryUser(List<User> userList, BaseUserFilter baseUserFilter) {
List<User> resultList = new ArrayList<>();
for (User user : userList) {
if (baseUserFilter.judge(user)) {
resultList.add(user);
}
}
return resultList;
}
完毕!调用代码如下:
@Test
public void test3() {
//查询年龄小于30的用户
List<User> users = queryUser(userList, new UserAgeLt30Filter());
users.forEach(data -> System.out.println(data));
System.out.println("华丽的分割线");
//查询年龄大于30的用户
List<User> users2 = queryUser(userList, new UserAgeGt30Filter());
users2.forEach(data -> System.out.println(data));
}
后续增加其余的过滤需求都可以直接增加 BaseUserFilter 接口的 对应实现,比如查询分数 及格的用户,不及格的用户 等等!