Java 接口的定义重构学生管理系统

重构目标:将系统的核心操作抽象为接口,从而解耦业务逻辑与具体实现。后续可以轻松替换存储方式(如从内存换成数据库)或增加新功能

  1. 定义核心接口

```java

// 学生实体类

public class Student {

private String id;

private String name;

private int age;

// 构造方法、getter/setter 省略

}

// 学生管理接口 - 定义所有对外提供的操作

public interface StudentService {

boolean addStudent(Student student);

boolean deleteStudent(String id);

boolean updateStudent(Student student);

Student findStudentById(String id);

List<Student> findAllStudents();

}

```


  1. 基于内存的实现(原有系统可能长这样)

```java

// 原来的实现:直接使用 ArrayList,业务代码与具体存储耦合

public class MemoryStudentManager {

private List<Student> students = new ArrayList<>();

public boolean addStudent(Student s) { ... }

public Student findStudentById(String id) { ... }

// ...

}

```


  1. 重构:让实现类实现接口

```java

// 重构后:实现 StudentService 接口

public class MemoryStudentService implements StudentService {

private List<Student> students = new ArrayList<>();

@Override

public boolean addStudent(Student student) {

if (findStudentById(student.getId()) != null) {

return false; // 已存在

}

return students.add(student);

}

@Override

public boolean deleteStudent(String id) {

return students.removeIf(s -> s.getId().equals(id));

}

@Override

public boolean updateStudent(Student student) {

Student old = findStudentById(student.getId());

if (old == null) return false;

old.setName(student.getName());

old.setAge(student.getAge());

return true;

}

@Override

public Student findStudentById(String id) {

return students.stream()

.filter(s -> s.getId().equals(id))

.findFirst()

.orElse(null);

}

@Override

public List<Student> findAllStudents() {

return new ArrayList<>(students);

}

}

```


  1. 使用接口编程(客户端代码)

```java

public class StudentManagementSystem {

private StudentService studentService;

// 通过构造方法注入具体的实现(依赖注入)

public StudentManagementSystem(StudentService studentService) {

this.studentService = studentService;

}

public void showAllStudents() {

studentService.findAllStudents().forEach(System.out::println);

}

// 其他业务方法...

}

// 主程序

public class Main {

public static void main(String\[\] args) {

// 只需替换这一行,就可以切换存储方式

StudentService service = new MemoryStudentService();

// StudentService service = new DatabaseStudentService(); // 未来扩展

StudentManagementSystem system = new StudentManagementSystem(service);

system.addStudent(new Student("1", "张三", 20));

system.showAllStudents();

}

}

```


  1. 重构带来的好处

方面 重构前(具体类) 重构后(接口)

扩展性 要换存储方式必须修改大量代码 新增 DatabaseStudentService 即可,符合开闭原则

测试性 单元测试必须依赖真实的列表 可以传入 Mock 实现,便于隔离测试

可维护性 业务逻辑与存储细节混杂 接口清晰定义了契约,实现者各司其职

多态性 不支持多种管理策略 可以用同一个 StudentManagementSystem 配合不同实现


  1. 接口定义中的进阶设计(可选)

你还可以在接口中添加默认方法或静态方法,提供公共逻辑:

```java

public interface StudentService {

// 核心抽象方法 ...

// 默认方法:检查学生是否成年

default boolean isAdult(Student student) {

return student.getAge() >= 18;

}

// 静态方法:创建默认的内存实现

static StudentService newMemoryInstance() {

return new MemoryStudentService();

}

}

```

使用时:StudentService service = StudentService.newMemoryInstance();


总结

通过接口的定义,将学生管理系统的操作契约与具体实现分离。这是面向对象设计中的面向接口编程原则,也是 Spring 等框架的核心思想。重构后的系统可以轻松应对需求变化(如从内存存储改为数据库存储),同时极大提升了代码的可测试性和可维护性。

相关推荐
迷途之人不知返22 分钟前
算法系列2:滑动窗口
算法
IT爱学堂23 分钟前
尚硅谷 - 2025年3月Java+AI大模型应用开发
java·开发语言·人工智能
有点。23 分钟前
C++认识数
开发语言·c++
Herbert_hwt31 分钟前
C语言零基础入门:循环控制与数据类型详解
c语言·数据结构·算法
小贤plus1 小时前
SpringBoot 三大核心注解精讲:@ControllerAdvice、@RestControllerAdvice、@Validated 分组校验(实战)
java
吠品2 小时前
Java byte数组与String互转:编码细节与踩坑记录
java·linux·服务器
W_326002 小时前
Python文件进阶:一维数据与 CSV 文件读写
开发语言·python
晚风醉蝶2 小时前
1-6-插入排序-InsertionSort
java·数据结构·排序算法
Tyler_TXZ2 小时前
C++C语言之——二叉树
c语言·开发语言·数据结构·c++·二叉树
Tisfy2 小时前
LeetCode 3090.每个字符最多出现两次的最长子字符串:二重循环 / 滑动窗口
算法·leetcode·字符串·题解·模拟·双指针·滑动窗口