302
社区成员
发帖
与我相关
我的任务
分享@[TOC](文章目录)
---
## 1. 程序架构设计与演进
本单元的任务是解析并展开包含加减、括号、幂次及多层嵌套因子的表达式。我采用了**递归下降算法**进行建模。
### 1.1 总体 UML 类图
通过 `Parser`(解析器)将输入的字符串流转化为层次化的对象树。
```mermaid
classDiagram
class MainClass {
+main(args: String[])
}
class Parser {
-lexer: Lexer
+parseExpression(): Expression
+parseTerm(): Term
+parseFactor(): Factor
}
class Lexer {
-content: String
-curToken: String
+next()
+peek() String
}
class Expression {
-terms: ArrayList~Term~
+toPolynomial(): Polynomial
}
class Term {
-factors: ArrayList~Factor~
+toPolynomial(): Polynomial
}
class Factor <<interface>> {
+toPolynomial(): Polynomial
}
class Variable {
-exponent: BigInteger
}
class Number {
-value: BigInteger
}
class ExprFactor {
-expr: Expression
}
MainClass ..> Parser
Parser ..> Lexer
Expression "1" *-- "n" Term
Term "1" *-- "n" Factor
Factor <|.. Variable
Factor <|.. Number
Factor <|.. ExprFactor
```
### 1.2 迭代演进历程
* **HW1**:初步建立 `Expression-Term-Factor` 结构。主要挑战在于处理正负号和基本的项合并。
* **HW2**:引入了括号嵌套。得益于 HW1 的层次化设计,只需在 `Factor` 接口下新增 `ExprFactor` 实现类,即可通过递归调用完美支持嵌套。
* **HW3**:进一步支持多层指数与因子嵌套。核心计算逻辑保持不变,体现了 OCP(开闭原则)的优越性。
---
## 2. 代码度量分析 (Metrics Analysis)
利用 IntelliJ IDEA 插件对工程复杂度进行度量,分析核心方法的内聚与耦合。
### 2.1 方法复杂度 (Method Metrics)
| 方法名 | 循环复杂度 (v(G)) | 认知复杂度 | 核心逻辑说明 |
| :--- | :---: | :---: | :--- |
| `Parser.parseFactor()` | 11 | 14 | 解析不同类型的因子分支 |
| `Polynomial.multiply()` | 7 | 9 | 实现多项式间的乘法分配律 |
| `Lexer.next()` | 6 | 5 | 状态机识别下一个 Token |
### 2.2 架构评价
* **优点**:各组件职责单一,`Lexer` 只负责切分字符串,`Parser` 只负责构建对象,计算逻辑完全封装在 `Polynomial` 类中。
* **缺点**:在解析因子时,由于存在多种可能的输入模式,`parseFactor` 方法中存在较多的 `if-else` 分支,导致认知复杂度偏高,后续可考虑使用**工厂模式**进行重构。
---
## 3. Bug 分析与互测心得
### 3.1 自身 Bug 分析
* **HW1 强测记录**:未出现 Bug。
* **HW2 强测记录**:在处理 `-(...)` 这种项首负号且括号内包含多项式时,出现了符号分派错误。
* **根源**:未能正确处理负号与 `ExprFactor` 的结合优先级。
* **修复**:在 `Term` 层级引入一个 `sign` 因子,统一处理项内部的符号乘积。
### 3.2 互测策略与体会
互测中,我主要通过以下两种方式寻找他人的 Bug:
1. **黑盒测试**:编写简单的 Python 脚本,利用 `random` 库构造复杂的嵌套表达式,并使用 `sympy` 进行结果比对。
2. **白盒审计**:重点关注对方代码中处理“前导 0”、“大数运算”以及“空括号”的边界逻辑。
3. **心得**:优秀的程序不仅要能跑通主逻辑,更要能抵御各种“非法但合规”的极端输入。
---
## 4. 面向对象思维的实践与体会
### 4.1 从“怎么做”到“谁去做”
在 C 语言阶段,我的思维是:如何遍历字符串并算出结果。
在 Java OO 阶段,我的思维转变为:定义 `Expression`、`Term` 这些对象,它们自己知道如何计算并返回一个 `Polynomial`。
### 4.2 封装与多态的应用
通过 `Factor` 接口,我成功将不同种类的运算单元抽象化。无论是一个简单的数字,还是一个复杂的括号表达式,在 `Term` 的视角下它们都是平等的。这种**屏蔽实现细节、关注交互接口**的设计方式,极大地降低了代码的维护成本。
---
## 5. 总结
第一单元的作业是高强度的,但也让我深刻体会到了架构的威力。一个好的架构可以轻松应对需求的变更,而混乱的代码则会在迭代中走向崩溃。在接下来的单元中,我将继续深入理解 SOLID 原则,写出更优雅、更健壮的 Java 程序。
---