策略模式

Posted by New Boy on March 12, 2018

前言

所谓策略模式,就是可以采取不同的策略去完成我们需要的过程。举个简单的例子来说,一个商场每到节假日就会举办促销活动,不同的节假日有着不同的促销策略。如果在节假日要到时在进行修改,其实是非常不利于维护的,于是策略模式便有了用武之地。

实例实现

就比如有这么一个场景,一个班里有很多的学生,一次月考过后,老师手握全班同学的各门课的成绩,现在老师希望根据各门课对全班同学进行一个排名。据此场景,通过代码实现,comparator就是我们需要的策略

Teacher:

public class Teacher {
    private List<Student> students = new ArrayList<Student>();

    private Comparator<? super Student>  comparator;

    Teacher() {
    }

    public Teacher addStudent(Student student) {
        students.add(student);
        return this;
    }

    public void showRankByStrategy() {
        Collections.sort(students, comparator);
        for (Student student : students) {
            System.out.println(student.toString());
        }
    }

    public Comparator<? super Student> getComparator() {
        return comparator;
    }

    public void setComparator(Comparator<? super Student> comparator) {
        this.comparator = comparator;
    }
}

Student:

public class Student {
    private int mathGrade;

    private int historyGrade;

    private int scienceGrade;

    private int englishGrade;

    private String name;

    public Student(int mathGrade, int historyGrade, int scienceGrade, int englishGrade, String name) {
        this.mathGrade = mathGrade;
        this.historyGrade = historyGrade;
        this.scienceGrade = scienceGrade;
        this.englishGrade = englishGrade;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return mathGrade == student.mathGrade &&
                historyGrade == student.historyGrade &&
                scienceGrade == student.scienceGrade &&
                englishGrade == student.englishGrade &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mathGrade, historyGrade, scienceGrade, englishGrade, name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "mathGrade=" + mathGrade +
                ", historyGrade=" + historyGrade +
                ", scienceGrade=" + scienceGrade +
                ", englishGrade=" + englishGrade +
                ", name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMathGrade() {
        return mathGrade;
    }

    public void setMathGrade(int mathGrade) {
        this.mathGrade = mathGrade;
    }

    public int getHistoryGrade() {
        return historyGrade;
    }

    public void setHistoryGrade(int historyGrade) {
        this.historyGrade = historyGrade;
    }

    public int getScienceGrade() {
        return scienceGrade;
    }

    public void setScienceGrade(int scienceGrade) {
        this.scienceGrade = scienceGrade;
    }

    public int getEnglishGrade() {
        return englishGrade;
    }

    public void setEnglishGrade(int englishGrade) {
        this.englishGrade = englishGrade;
    }
}

StrategyFactory(保存student中各个字段的比较器)

public class StrategyFactory {

    private static Map<String, Comparator> strategyList = new HashMap<>();

    static {
        Field[] fields = Student.class.getDeclaredFields();
        Method[] methods = Student.class.getMethods();
        //System.out.println("asdasd");
        for (Field field : fields) {
            field.setAccessible(true);
            strategyList.put(field.getName(), new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    try {
                        Object obj1 = field.get(o1);
                        Object obj2 = field.get(o2);
                        if (obj1 instanceof Integer) {
                            Integer fieldOne = (Integer) obj1;
                            Integer fieldTwo = (Integer) obj2;
                            if (fieldOne.compareTo(fieldTwo) >= 1) {
                                return 1;
                            } else if (fieldOne.compareTo(fieldTwo) <= -1) {
                                return -1;
                            }
                        } else if (obj1 instanceof String){
                            String fieldOne = (String) obj1;
                            String fieldTwo = (String) obj2;
                            if (fieldOne.compareTo(fieldTwo) >= 1) {
                                return 1;
                            } else if (fieldOne.compareTo(fieldTwo) <= -1) {
                                return -1;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return 0;
                }
            });
        }
    }

    public static Comparator getStrategy(String strategyName) {
        return strategyList.get(strategyName);
    }
}

测试程序

public class MainTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.addStudent(new Student(1,2,3,4, "a"))
                .addStudent(new Student(4,1,13,1, "b"))
                .addStudent(new Student(5,2,23,3, "c"))
                .addStudent(new Student(7,5,7,2, "d"))
                .addStudent(new Student(3,13,1,10, "e"));

        Comparator strategy = StrategyFactory.getStrategy("scienceGrade");
        teacher.setComparator(strategy);
        teacher.showRankByStrategy();
    }
}