重构仅含常量与纯函数的类:是否误用面向对象抽象?
你的面向对象抽象确实存在误用,重构方案如下
问题分析
- 混淆实体与逻辑职责:每个
Subject子类既承载课程数据(名称、学分),又负责依赖判断逻辑,但所有子类都是无状态的,实例化它们完全多余——本质是在用类模拟枚举+静态方法,违背了面向对象“封装状态与行为”的核心思想。 - 抽象类设计冗余:
Subject强制子类实现的属性和方法,并未利用实例状态,反而导致每个课程都要重复编写无意义的模板代码。 - 依赖逻辑硬编码且重复:高阶课程的依赖列表都硬编码在子类方法中,新增或修改课程时需要重复编写相似逻辑,维护成本高。
重构方案
核心思路:拆分职责,配置化管理
- 分离数据与逻辑:把课程元数据(名称、学分)和依赖判断逻辑拆分为独立模块,各自承担单一职责。
- 配置化依赖关系:将课程的前置依赖从代码中抽离,用配置方式维护,避免硬编码带来的维护负担。
重构后的代码
using System; using System.Collections.Generic; using System.Linq; // 课程类型枚举,统一管理课程标识 public enum CourseType { CalculusI, Algebra, CalculusII, CalculusIII } // 课程元数据类,专门存储课程基础信息与依赖关系 public class CourseMetadata { public CourseType Type { get; set; } public string Name { get; set; } public int Credit { get; set; } public List<CourseType> Prerequisites { get; set; } = new List<CourseType>(); } // 课程依赖服务,专门处理依赖判断逻辑 public class CoursePrerequisiteService { private readonly Dictionary<CourseType, CourseMetadata> _courseMap; public CoursePrerequisiteService(List<CourseMetadata> courseMetadatas) { _courseMap = courseMetadatas.ToDictionary(m => m.Type); } // 递归查找目标课程的第一个未完成前置依赖 public CourseMetadata FindMissingPrerequisite(CourseType targetCourse, List<CourseType> learnedCourses) { var targetMetadata = _courseMap[targetCourse]; foreach (var prerequisite in targetMetadata.Prerequisites) { var missing = FindMissingPrerequisite(prerequisite, learnedCourses); if (missing != null) { return missing; } if (!learnedCourses.Contains(prerequisite)) { return _courseMap[prerequisite]; } } return null; } } public class Program { public static void Main(string[] args) { // 集中配置所有课程的元数据与依赖关系 var courseMetadatas = new List<CourseMetadata> { new CourseMetadata { Type = CourseType.CalculusI, Name = "MTH101", Credit = 3 }, new CourseMetadata { Type = CourseType.Algebra, Name = "MTH201", Credit = 3 }, new CourseMetadata { Type = CourseType.CalculusII, Name = "MTH102", Credit = 3, Prerequisites = { CourseType.CalculusI } }, new CourseMetadata { Type = CourseType.CalculusIII, Name = "MTH103", Credit = 3, Prerequisites = { CourseType.CalculusII } } }; var service = new CoursePrerequisiteService(courseMetadatas); var learnedCourses = new List<CourseType> { CourseType.Algebra }; var missingCourse = service.FindMissingPrerequisite(CourseType.CalculusIII, learnedCourses); if (missingCourse != null) { Console.WriteLine(missingCourse.Name); // 输出 MTH101 } else { Console.WriteLine("已满足所有前置条件"); } } }
重构优势
- 职责清晰:元数据类存信息,服务类处理逻辑,符合单一职责原则。
- 维护成本低:新增/修改课程只需调整配置,无需改动逻辑代码。
- 效率更高:避免了无意义的类实例化,代码简洁且易于理解。
内容的提问来源于stack exchange,提问作者FEEDC0DE
相关产品推荐
相关产品推荐

