一、案例背景
在学校管理系统中,学生信息管理模块需要满足不同统计需求的灵活切换。本案例通过策略模式实现以下功能:
-
打印全班学生信息
-
计算全班平均成绩
支持两种统计方案:
-
基础方案:直接统计
-
增强方案:显示性别分布,计算平均分时去掉最高/低分
二、设计思路
1. UML类图
-
classDiagram class StudentOp { <<interface>> +show(students) +ping(students) } class BasicStudentOperation class EnhancedStudentOperation StudentOp <|.. BasicStudentOperation StudentOp <|.. EnhancedStudentOperation class StudentCom { -students: ArrayList -strategy: StudentOp +show() +ping() }
2. 策略模式优势
-
算法独立变化
-
运行时动态切换
-
避免多重条件判断
-
三、代码实现(优化版)
1. 学生实体类
public class Student { private String name; private char gender; // 字段名优化 private double score; // 类型优化 // 构造方法、getter/setter省略 }
2. 策略接口定义
public interface StudentStrategy { void displayInfo(List<Student> students); void calculateAverage(List<Student> students); }
3. 基础实现方案
public class BasicStrategy implements StudentStrategy { @Override public void displayInfo(List<Student> students) { System.out.println("=== 学生信息列表 ==="); students.forEach(s -> System.out.printf("姓名:%s\t性别:%c\t成绩:%.1f%n", s.getName(), s.getGender(), s.getScore())); } @Override public void calculateAverage(List<Student> students) { double avg = students.stream() .mapToDouble(Student::getScore) .average() .orElse(0); System.out.printf("班级平均分:%.2f%n", avg); } }
4. 增强实现方案
public class EnhancedStrategy implements StudentStrategy { @Override public void displayInfo(List<Student> students) { long maleCount = students.stream() .filter(s -> s.getGender() == '男').count(); System.out.println("=== 详细信息 ==="); System.out.println("男生人数:" + maleCount); System.out.println("女生人数:" + (students.size() - maleCount)); BasicStrategy base = new BasicStrategy(); base.displayInfo(students); } @Override public void calculateAverage(List<Student> students) { DoubleSummaryStatistics stats = students.stream() .mapToDouble(Student::getScore) .summaryStatistics(); if(students.size() <= 2) { System.out.println("学生人数不足,无法去除极值"); return; } double avg = (stats.getSum() - stats.getMax() - stats.getMin()) / (students.size() - 2); System.out.printf("调整后平均分(去除极值):%.2f%n", avg); } }
5. 上下文管理类
public class StudentManager { private List<Student> students = new ArrayList<>(); private StudentStrategy strategy; // 动态设置策略 public void setStrategy(StudentStrategy strategy) { this.strategy = strategy; } public void executeDisplay() { strategy.displayInfo(students); } public void executeCalculate() { strategy.calculateAverage(students); } // 初始化测试数据 public StudentManager() { students.add(new Student("张三", '男', 92.5)); students.add(new Student("李四", '女', 88.0)); students.add(new Student("王五", '男', 95.5)); } }
四、使用示例
public class Main { public static void main(String[] args) { StudentManager manager = new StudentManager(); // 使用基础策略 manager.setStrategy(new BasicStrategy()); manager.executeDisplay(); manager.executeCalculate(); System.out.println("\n==== 切换策略 ====\n"); // 使用增强策略 manager.setStrategy(new EnhancedStrategy()); manager.executeDisplay(); manager.executeCalculate(); } }
输出结果:
=== 学生信息列表 === 姓名:张三 性别:男 成绩:92.5 ... 班级平均分:92.00 ==== 切换策略 ==== === 详细信息 === 男生人数:2 女生人数:1 ... 调整后平均分(去除极值):92.50