文章目录
- 什么是策略设计模式
- 策略设计模式的作用
- 策略设计模式的实现方式
-
- 实现方式一:使用接口实现类
- 实现方式二:使用内部类
- 实现方式三:使用Lambda表达式
- 策略设计模式实现代码:过滤器实例
-
- 代码实例:控制台输出
什么是策略设计模式
创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,这就是策略设计模式。
这类的方法所包含要执行的算法中固定不变的部分,而策略包含变化的部分,策略就是传递进去的参数对象,它包含要执行的代码。
策略设计模式的作用
在接口中常见的用法就是策略设计模式,在之指定的接口里面编写执行的方法,你可以用任何的对象来调用我的方法,只要你的对象遵循我的接口,实现我的方法,增加了灵活性和复用性。
策略设计模式的实现方式
基本实现需要一个泛型接口,实体类,接口抽象方法的实现。
实现方式一:使用接口实现类
通过具体类实现接口的抽象方法,泛型参数可以用不同的实体类传参,缺点就是多个不同接口实现需要创建多个接口实现类。
实现方式二:使用内部类
通过内部类直接实现接口的抽象方法,缺点还是存在部分冗余代码
实现方式三:使用Lambda表达式
通过Lambda表达式,简洁优雅。
策略设计模式实现代码:过滤器实例
以下代码实例包含上面三种实现方式,根据员工的不同信息进行过滤。
1.接口
/**
* 策略模式之接口
*/
public interface StrategyInterface<T> {
//将满足条件的返回true
public boolean isReal(T t);
}
2.实体类
/**
* 策略模式之实体bean
*/
public class Employee {
private int age;
private String name;
private double salary;
//无参构造器,含有有参构造器,那必须先声明一个无参构造器,否则编译器会报错
public Employee() {
}
//重写toString()方法
@Override
public String toString() {
return "Employee{" +
"age=" + age +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
//重写equals()方法,用于判断两个对象是否相等,通过hashcode计算,所以重写equals方法是,也必须重写hashcode方法,
// 为了避免hashSet\hashTable\hashMap比较时出现不可预期的结果,
// 比如通过hashcode计算出相同的key值,在Map中。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return age == employee.age &&
Double.compare(employee.salary, salary) == 0 &&
Objects.equals(name, employee.name);
}
//重写hashCode()方法,用于散列集合的查找
@Override
public int hashCode() {
return Objects.hash(age, name, salary);
}
//全参数构造器,主要用于初始化赋值,若参数多,不建议使用这种方式
public Employee(int age, String name, double salary) {
this.age = age;
this.name = name;
this.salary = salary;
}
//set和get方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
3.接口实现类(实现方式一使用到)
/**
* 策略接口的具体实现类,实现接口的抽象方法
*/
public class StrategyImpl_1 implements StrategyInterface<Employee>{
@Override
public boolean isReal(Employee e) {
return e.getAge()>18;
}
}
4.实例调用
/**
* 策略模式之过滤实例
*/
public class StrategyDemo {
public static void main(String[] args) {
StrategyDemo strategyDemo=new StrategyDemo();
//构造原数据
List<Employee> listEmp= Arrays.asList(
new Employee(18,"zhangsan",555),
new Employee(17,"lisi",666),
new Employee(16,"huangwu",777),
new Employee(19,"liuliu",888)
);
/**
* 使用方法一:需要创建接口对应的实现类,及实现接口的抽象方法
*/
System.out.println("--------接口实现类方式:------------------");
//1.1 调用接口的具体实现方法,传入具体实现类,具体过滤作用在具体实现类
List<Employee> listEmp_result= strategyDemo.filterEmp(listEmp,new StrategyImpl_1());
//1.2 遍历结果
/* for (Employee ee:listEmp_result
) {
System.out.println(ee.getAge()+","+ee.getName()+","+ee.getSalary());
}*/
listEmp_result.forEach(System.out::println);
/**
* 使用方法二:使用匿名内部类实现接口,不需要创建接口的具体实现类,具体实现方法直接在内部类方法里面实现
*
*/
System.out.println("--------匿名内部类方式:------------------");
//2.1 使用匿名内部类创建接口对象,并实现接口的抽象方法,供过滤方法调用
List<Employee> employeeList= strategyDemo.filterEmp(listEmp, new StrategyInterface<Employee>() {
@Override
public boolean isReal(Employee employee) {
return employee.getSalary()<=666;//实现的过滤功能,可以自定义
}
});
//2.2遍历
/* for (Employee ee:employeeList
) {
System.out.println(ee.getAge()+","+ee.getSalary()+","+ee.getName());
}*/
employeeList.forEach(System.out::println);
/**
* 使用方式三:使用Lambda表达式,去除冗余代码,精简代码
*
*/
System.out.println("------使用lamba表达式方法:-------------");
List<Employee> list_lambda= strategyDemo.filterEmp(employeeList,(e)->e.getAge()>15);
list_lambda.forEach(System.out::println);
/* for (Employee ee:list_lambda
) {
System.out.println(ee.getAge()+","+ee.getSalary()+","+ee.getName());
}*/
}
/**
* 策略模式之过滤器实例,通过接口的泛型参数作用,调用接口方法判断是否符合要求,实现过滤的功能;
* 使用时只要传入该接口的具体实现类即可
* @param list,需要过滤的原数据
* @param semp,过滤经过的接口,需要指定具体的泛型参数类型,调用具体的接口实现类的方法进行判断。
* @return
*/
public List<Employee> filterEmp(List<Employee> list,StrategyInterface<Employee> semp){
List<Employee> resultList=new ArrayList<>();
for (Employee ee: list
) {
if(semp.isReal(ee)){
resultList.add(ee);
}
}
return resultList;
}
}
代码实例:控制台输出
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90zZiBXMHpFa5YlW6Z1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1IDO2QzMxATMwMDMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)