设计模式(十)strategy策略模式

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

设计模式(十)strategy策略模式

2. strategy策略模式

  1. strategy模式
    在业务开发中,需求会经常变化,这时候将逻辑代码写死是非常不利于应对需求变化的,这时候就可以采取策略模式,来一种需求,换一种策略。这样只有需求改动部分需要整体变化,其他部分不需要改动。
  2. 案例程序
  • 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);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值