设计模式(十)strategy策略模式
2. strategy策略模式
- strategy模式
在业务开发中,需求会经常变化,这时候将逻辑代码写死是非常不利于应对需求变化的,这时候就可以采取策略模式,来一种需求,换一种策略。这样只有需求改动部分需要整体变化,其他部分不需要改动。 - 案例程序
- java bean
class User{
private String name;
private int age;
private double salary;
public User(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
- main方法及test类
public class StrategyTest {
private static List<User> list = new ArrayList<User>();
static {
list.add(new User("zs", 34, 3000));
list.add(new User("ls", 35, 3000));
list.add(new User("ws", 2, 300));
list.add(new User("cs", 3, 45600));
list.add(new User("hs", 8, 7000));
}
public static void main(String[] args) {
// 例如针对数据筛选,产品经理可能会随时调整数据筛选尺度
// 分别根据名字筛选,工资筛选,年龄筛选
test1();
}
}
- 解决方法一
// 传统遍历方法
private static void test1() {
// 需求1,根据名字筛选
List<User> nameUsers = new ArrayList<>();
for (User user : list) {
if(user.getName().startsWith("l")){
nameUsers.add(user);
}
}
System.out.println("nameUsers:---------------");
for (User user : nameUsers) {
System.out.println(user);
}
// 根据年龄筛选
List<User> ageUsers = new ArrayList<User>();
for (User user : list) {
if(user.getAge() > 10) {
ageUsers.add(user);
}
}
System.out.println("ageUsers---------------");
for (User user : ageUsers) {
System.out.println(user);
}
// 根据工资筛选
List<User> salUsers = new ArrayList<>();
for (User user : list) {
if(user.getSalary() > 2000){
salUsers.add(user);
}
}
System.out.println("salUsers---------------");
for (User user : salUsers) {
System.out.println(user);
}
}
- 解决方法二
使用接口,将公共代码抽离,然后再将不同的筛选过滤逻辑抽离到一个一个的接口实现类中
公共的循环遍历代码
// 将过滤的公共代码抽离,只需要保留一份
private static List<User> getFilterList(FilterInterface filterInterface) {
List<User> res = new ArrayList<>();
for (User user : list) {
if(filterInterface.filter(user)) {
res.add(user);
}
}
return res;
}
接口以及对应接口实现类
interface FilterInterface {
boolean filter(User user);
}
class FilterInterfaceImplAge implements FilterInterface{
@Override
public boolean filter(User user) {
return user.getAge() > 10;
}
}
class FilterInterfaceImplName implements FilterInterface{
@Override
public boolean filter(User user) {
return user.getName().startsWith("l");
}
}
class FilterInterfaceImplSal implements FilterInterface{
@Override
public boolean filter(User user) {
return user.getSalary()>2000;
}
}
实际使用代码,这里可以看到,重复的for循环遍历代码被抽离出去了,剩下的只有不同的筛选过滤逻辑
private static void test2() {
// 需求1,根据名字筛选
List<User> nameUsers = getFilterList(new FilterInterfaceImplName());
System.out.println("nameUsers:---------------");
for (User user : nameUsers) {
System.out.println(user);
}
// 根据年龄筛选
List<User> ageUsers = getFilterList(new FilterInterfaceImplAge());
System.out.println("ageUsers---------------");
for (User user : ageUsers) {
System.out.println(user);
}
// 根据工资筛选
List<User> salUsers = getFilterList(new FilterInterfaceImplSal());
System.out.println("salUsers---------------");
for (User user : salUsers) {
System.out.println(user);
}
}
- 解决方法三
匿名内部类,基于方法二,这时候不需要每一种筛选要求都创建一个接口实现类,而是使用匿名内部类方式,就是创建一个实现了这个筛选接口的类,但是没有名字。这样就不需要重复创建很多的接口实现类
private static void test3() {
// 需求1,根据名字筛选
List<User> nameUsers = getFilterList(new FilterInterface() {
@Override
public boolean filter(User user) {
return user.getName().startsWith("l");
}
});
System.out.println("nameUsers:---------------");
for (User user : nameUsers) {
System.out.println(user);
}
// 根据年龄筛选
List<User> ageUsers = getFilterList(new FilterInterface() {
@Override
public boolean filter(User user) {
return user.getAge() > 10;
}
});
System.out.println("ageUsers---------------");
for (User user : ageUsers) {
System.out.println(user);
}
// 根据工资筛选
List<User> salUsers = getFilterList(new FilterInterface() {
@Override
public boolean filter(User user) {
return user.getSalary()>2000;
}
});
System.out.println("salUsers---------------");
for (User user : salUsers) {
System.out.println(user);
}
}

本文通过实例讲解策略模式在Java中的应用,展示如何通过策略模式应对业务需求的频繁变化,特别是在数据筛选场景下,策略模式能够有效减少代码重复,提高代码的可维护性和扩展性。
1853

被折叠的 条评论
为什么被折叠?



