From b4b0f3e09ddb00a8dfcd8b056b48e2d854649a71 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:14:00 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE=E8=AE=A1.m?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/类的设计.md | 274 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 239 insertions(+), 35 deletions(-) diff --git a/doc/类的设计.md b/doc/类的设计.md index d6dfe3a..28d3aba 100644 --- a/doc/类的设计.md +++ b/doc/类的设计.md @@ -1,35 +1,239 @@ -#类的设计 -##User(用户实体) -###作用: - 存储用户账户信息,包括用户名、密码和用户类型 -###属性: - private String username; // 用户名 - private String password; // 密码 - private String userType; // 用户类型(小学/初中/高中) -###方法: - public boolean validateCredentials(String inputUsername, String inputPassword) - // 验证用户名和密码是否匹配 - - // Getter和Setter方法 - public String getUsername() - public void setUsername(String username) - public String getPassword() - public void setPassword(String password) - public UserType getUserType() - public void setUserType(String userType) - -##UserManager(用户管理类) -###作用: - 管理用户登录状态、类型切换和用户认证 -###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 -###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() +# 试卷生成系统类设计说明文档 + +本说明文档详细描述系统中各个核心类的设计目的、职责、关键属性及方法实现逻辑,帮助开发者理解系统内部结构并进行维护或扩展。 + +--- + +## 1. User 类 + +### 功能概述 +User 是用户信息的封装类,用于存储单个用户的登录凭证和所属学段类型。 + +### 属性 +- `username`:字符串类型,表示用户名。 +- `password`:字符串类型,表示用户密码(明文存储,仅用于演示)。 +- `userType`:字符串类型,表示用户类型,取值为“小学”、“初中”或“高中”。 + +### 方法 +- **构造方法** `User(String username, String password, String userType)` + 初始化用户对象,设置用户名、密码和用户类型。 + +- `getUsername()` / `setUsername(String username)` + 获取或设置用户名。 + +- `getPassword()` / `setPassword(String password)` + 获取或设置密码。 + +- `getUserType()` / `setUserType(String userType)` + 获取或设置用户类型。 + +- `validateCredentials(String inputUsername, String inputPassword)` + 验证输入的用户名和密码是否与当前用户匹配。返回布尔值,用于登录判断。 + +--- + +## 2. UserManager 类 + +### 功能概述 +UserManager 负责管理所有用户账户、处理登录逻辑,并维护当前登录用户状态。 + +### 属性 +- `users`:`Map` 类型,以用户名为键存储所有预设用户。 +- `currentUser`:`User` 类型,表示当前已登录的用户。 +- `currentType`:`String` 类型,缓存当前用户类型(冗余字段,可由 currentUser 推导)。 + +### 方法 +- **构造方法** `UserManager()` + 调用 `initializeUsers()` 初始化9个预设用户(3小学 + 3初中 + 3高中)。 + +- `initializeUsers()` + 向 users 映射中添加预设用户对象,用户名如“张三1”,密码均为“123”,类型按学段分配。 + +- `login(String username, String password)` + 实现登录逻辑: + - 若用户名不存在,提示“该账号不存在”; + - 若密码错误,提示“密码错误”; + - 验证成功,设置 `currentUser` 和 `currentType`,返回 true。 + +- `logout()` + 清空当前用户状态(设为 null)。 + +- `switchUserType(String newType)` + 允许在已登录状态下切换用户类型(实际项目中此方法未被使用,主流程通过重新获取 QuestionSetting 实现切换)。 + +- `isLoggedIn()` + 判断是否有用户登录(检查 `currentUser != null`)。 + +- `getCurrentUser()` + 返回当前登录的 `User` 对象,供其他模块获取用户信息。 + +--- + +## 3. QuestionSetting 接口 + +### 功能概述 +定义题目生成器的统一契约,确保所有学段题目生成器具有相同调用方式。 + +### 方法 +- `Expression setQuestion(int count)` + 根据指定的操作数数量 `count`(通常为3),生成一个符合当前学段要求的数学表达式对象。返回 `Expression` 实例。 + +--- + +## 4. AbstractQuestionSetting 抽象类 + +### 功能概述 +作为所有题目生成器的基类,提供通用工具方法,减少代码重复。 + +### 属性 +- `RANDOM`:静态 Random 实例,用于生成随机数,保证线程安全且全局一致。 + +### 方法 +- `getRandomOperator()` + 从 `{"+", "-", "*", "/"}` 中随机返回一个四则运算符。 + +- `getRandomNumber()` + 生成 1 到 99 的随机整数(含1和99),并返回其字符串形式。 + +- `getPriority(String operator)` + 返回运算符的优先级数值,用于括号判断: + - 三角函数、平方、开方:优先级 3 + - 乘、除:优先级 2 + - 加、减:优先级 1 + - 其他或 null:返回 0 或 -1 + +- `addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild)` + 根据运算优先级决定是否为子表达式添加括号: + - 子表达式无主运算符(即为纯数字),不加括号 + - 子优先级 < 父优先级,加括号 + - 若为右子表达式,且父运算符为 - 或 /,即使优先级相等也加括号(如 a - (b - c) 而非 a - b - c) + +--- + +## 5. PrimaryQuestionSetting 类(小学) + +### 功能概述 +实现小学阶段的题目生成逻辑,仅包含四则运算,并保证题目合理性。 + +### 方法 +- `setQuestion(int count)` + 递归生成表达式: + - 若 count == 1,返回一个随机数字; + - 否则将操作数拆分为左右两部分,递归生成左右子表达式; + - 随机选择运算符; + - 若为除法且右值为0,重新生成右子表达式; + - 若为减法且左值 < 右值,交换左右子表达式以保证结果非负; + - 使用 `addParenthesesIfNeeded` 处理括号; + - 返回最终表达式对象。 + +小学题目不包含任何一元运算符(如平方、三角函数),也不强制包含特定符号。 + +--- + +## 6. MiddleQuestionSetting 类(初中) + +### 功能概述 +在小学基础上增加平方(²)和平方根(√)运算,并确保每道题至少包含其中一种。 + +### 新增方法 +- `applyUnaryOperator(Expression child, String operator)` + 对子表达式应用一元运算符: + - 平方(²):若子表达式为纯数字,则直接拼接“²”;否则加括号后拼接,如 `(a + b)²` + - 平方根(√):若子值为负,替换为新随机正数;若为纯数字,前缀“√”;否则写为 `√(表达式)` + +- `applyProbability(Expression result)` + 以 30% 概率对表达式应用平方或平方根运算,并更新主运算符。 + +- `generateFirstQuestion(int count)` + 与小学类似,但每次生成后调用 `applyProbability` 尝试添加一元运算。 + +- `setQuestion(int count)` + 循环调用 `generateFirstQuestion`,直到生成的表达式包含“²”或“√”,确保题目符合初中要求。 + +--- + +## 7. HighQuestionSetting 类(高中) + +### 功能概述 +在初中基础上增加三角函数(sin、cos、tan),并确保每道题至少包含一个三角函数。 + +### 新增方法 +- `applyUnaryOperator(Expression child, String operator)` + 扩展支持三角函数: + - `sin`/`cos`:直接包裹为 `sin(表达式)` 或 `cos(表达式)`,值为 `Math.round(Math.sin(Math.toRadians(value)))` + - `tan`:若输入角度为 90 + 180k(无定义点),则替换为新随机数,避免异常 + +- `applyProbability(Expression result)` + 以 30% 概率从 `{"²", "√", "sin", "cos", "tan"}` 中随机选择一元运算符应用。 + +- `generateFirstQuestion(int count)` + 逻辑同初中,但支持更多运算符。 + +- `setQuestion(int count)` + 循环生成,直到表达式包含 `sin`、`cos` 或 `tan` 中的任意一个。 + ⚠️ 三角函数结果被强制转换为整数,可能损失精度,但简化了题目形式。 + +--- + +## 8. Expression 类 + +### 功能概述 +封装一个数学表达式的文本形式、计算值及其主运算符,用于递归构建和值传递。 + +### 属性 +- `expression`:表达式的字符串表示(如 `"5 + 3"` 或 `"√(16)"`) +- `value`:表达式计算结果的整数值 +- `mainOperator`:表达式的主运算符(如 `"+"`、`"²"`、`"sin"`),若为纯数字则为 null + +### 方法 +- 构造方法 `Expression(String expression, int value, String mainOperator)` + 初始化表达式对象 + +- `getExpression()` / `setExpression(String expression)` + 获取或设置表达式字符串 + +- `getValue()` / `setValue(int value)` + 获取或设置计算值 + +- `getMainOperator()` / `setMainOperator(String mainOperator)` + 获取或设置主运算符 + +> 该类是表达式树的节点,支持在生成过程中传递结构与值。 + +--- + +## 9. QuestionSettingFactory 类 + +### 功能概述 +工厂类,根据用户类型字符串动态创建对应的题目生成器实例。 + +### 方法 +- `getQuestionSetting(String type)` + 使用 switch 表达式: + - `"小学"` → 返回 `new PrimaryQuestionSetting()` + - `"初中"` → 返回 `new MiddleQuestionSetting()` + - `"高中"` → 返回 `new HighQuestionSetting()` + - 其他 → 打印“类型错误”,返回 `null` + +> 该类解耦了用户类型与具体实现,便于扩展新学段。 + +--- + +## 10. FileManager 类 + +### 功能概述 +负责试卷的本地存储与题目重复性检查。 + +### 常量 +- `ROOT_PATH`:根目录路径,值为 `"./试卷/"` + +### 方法 +- `savePaper(User user, List questions)` + - 创建用户专属目录(如 `./试卷/张三1/`) + - 生成时间戳文件名(格式:`yyyy-MM-dd-HH-mm-ss.txt`) + - 以 UTF-8 编码写入题目,格式为 `1. 表达式\n\n2. 表达式\n\n...` + +- `checkQuestion(String question, User user)` + - 若用户目录不存在,返回 true(无需去重) + - 遍历该用户所有历史试卷文件 + - 对每行去除题号