策略模式是啥???
相信很多小伙伴第一次听到策略模式都觉得很懵逼,而且觉得它高深莫测... 也肯定想知道这种模式是用来干嘛的...
那么今天我们就来聊聊策略模式...
不跟你多BB直接上代码:
/**
- Description:
*
- @author zpzp6
- @create 2020/2020/9/9/21:07
- @since 1.0.0
*/
public class AgeTest {
// 此处Person为Person类获得的对象。参数分别对应 name(姓名),age(年龄),sex(性别),hobby(爱好)
Person p = new Person("荣荣", 19, "女", "旅游");
Person p2 = new Person("小舞", 18, "女", "跳舞");
Person p3 = new Person("史泰龙", 12, "男", "run");
Person p4 = new Person("成龙", 10, "男", "woman");
List<Person> people = Arrays.asList(p, p2, p3, p4);
}
这是一个普通的人员的一个类,此时如果想让你获得年龄大于10的List集合,你会怎么写?
相信很多小伙伴都会写,这还不简单!
/**
- Description:
*
- @author zpzp6
- @create 2020/2020/9/9/21:07
- @since 1.0.0
*/
public class AgeTest {
Person p = new Person("荣荣", 19, "女", "旅游");
Person p2 = new Person("小舞", 18, "女", "跳舞");
Person p3 = new Person("史泰龙", 12, "男", "run");
Person p4 = new Person("成龙", 10, "男", "woman");
List<Person> people = Arrays.asList(p, p2, p3, p4);
@Test
public void test(){
List<Person> personList =new ArrayList<>();
for (Person person : people) {
if(person.getAge()>10){
personList.add(person);
}
}
}
}
那如果现在想获得性别为女的人员呢? 很多小伙伴肯定也觉得这根本就不是事儿!
/**
- Description:
*
- @author zpzp6
- @create 2020/2020/9/9/21:07
- @since 1.0.0
*/
public class AgeTest {
Person p = new Person("荣荣", 19, "女", "旅游");
Person p2 = new Person("小舞", 18, "女", "跳舞");
Person p3 = new Person("史泰龙", 12, "男", "run");
Person p4 = new Person("成龙", 10, "男", "woman");
List<Person> people = Arrays.asList(p, p2, p3, p4);
@Test
public void test(){
List<Person> personList =new ArrayList<>();
for (Person person : people) {
if(person.getAge()>10){
personList.add(person);
}
}
}
@Test
public void tests(){
List<Person> personList =new ArrayList<>();
for (Person person : people) {
if(person.getSex().equals("女")){
personList.add(person);
}
}
System.out.println(personList);
}
}
那现在如果让你获得年龄长度大于2的人员集合,想让你获得爱好跳舞的人员,想让你...
是不是每个要求都要写一个长长的方法去判断?
其实我们会发现,其实要改的也就那么一句:
if(person.getXxx() 条件 xxx){
personList.add(person);
}
因此,我们可以采用策略模式来简化我们的代码。
首先,我们可以先声明一个接口。
package service;
/**
- @author zp
- @Title:
- @Package
- @Description:
- @date 2020/2020/9/9/20:45
*/
public interface MyPredicate {
public boolean test(T t);
}
然后,对于接口实现一个实现类。这个实现类就是用来做限制的。比如年龄大于10啊,性别为女啊...等等。 这里先用年龄进行测试。
/**
- FileName: AgeImpl
- Author: zp
- Date: 2020/2020/9/9/20:45
- Description:
*/
package service;
import bean.Person;
/**
- Description:
- @author zpzp6
- @create 2020/2020/9/9/20:45
- @since 1.0.0
*/
public class AgeImpl implements MyPredicate{
@Override
public boolean test(Person person) {
return person.getAge()>10;
}
}
之后,就是写一个策略模式的一个通用方法。
public List getPersonListByAge(List lists, MyPredicate mp) {
List<Person> list = new ArrayList<>();
for (Person person : lists) {
if (mp.test(person)) {
list.add(person);
}
}
return list;
}
最后,就可以随心所欲的使用你的限制条件的实现类来完成想要的操作了。这里我又写了一个通过姓名来作为限制条件的实现类:
/**
- FileName: NameImpl
- Author: zp
- Date: 2020/2020/9/9/21:15
- Description:
*/
package service;
import bean.Person;
/**
- Description:
- @author zpzp6
- @create 2020/2020/9/9/21:15
- @since 1.0.0
*/
public class NameImpl implements MyPredicate{
@Override
public boolean test(Person person) {
return person.getName().length()>1;
}
}
然后就是将实现类传进通用方法就行了。
/**
- FileName: AgeTest
- Author: zp
- Date: 2020/2020/9/9/21:07
- Description:
*/
import bean.Person;
import org.junit.Test;
import service.AgeImpl;
import service.MyPredicate;
import service.NameImpl;
import test.People;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
- Description:
*
- @author zpzp6
- @create 2020/2020/9/9/21:07
- @since 1.0.0
*/
public class AgeTest {
Person p = new Person("荣荣", 19, "女", "旅游");
Person p2 = new Person("小舞", 18, "女", "跳舞");
Person p3 = new Person("史泰龙", 12, "男", "run");
Person p4 = new Person("成龙", 10, "男", "woman");
List<Person> people = Arrays.asList(p, p2, p3, p4);
public List<Person> getPersonListByAge(List<Person> lists, MyPredicate<Person> mp) {
List<Person> list = new ArrayList<>();
for (Person person : lists) {
if (mp.test(person)) {
list.add(person);
}
}
return list;
}
@Test
public void getPeopleList(){
//通过年龄
List<Person> personListByAge = getPersonListByAge(people, new AgeImpl());
personListByAge.forEach(System.out::println);
System.out.println("------------------------------------------------");
//通过姓名
List<Person> personListByName = getPersonListByAge(people, new NameImpl());
personListByName.forEach(System.out::println);
}
}
比较比较之前的那种方式,如果让你像之前那样每个条件写个方法,那估计要写老长老长了吧!
怎么样?有没有觉得清爽很多呢?
代码是变轻爽了。但其中的东西需要自己好好揣摩一下。另外,这里的代码还有可以优化的地方。不知道你能不能看到呢?
其实就是使用JDK1.8 的 lambda表达式来处理接口的实现。
好了。关于策略模式暂时就先介绍到这里,我们下期再见~~