OO_unit1 总结

24373390-张丹婷 2026-03-27 23:00:43

最终项目类图分析与设计评估

1. 总体设计分析

该项目旨在解析、求值和化简一个复杂的数学表达式。该表达式支持双变量(x, y)、多层括号、指数函数、自定义函数(非递推与递推)、条件选择,甚至符号求导。

其核心架构思想是组合模式 (Composite Pattern) 和**延迟求值 (Lazy Evaluation)**。

  1. 组合模式

    • Factor 作为抽象构件接口,定义了所有表达式组件的共同行为 toPoly()
    • Expr(表达式)、Term(项)是组合节点,它们包含其他 Factor
    • Number(常数)、Variable(变量)、ExpFunc(指数函数)等是叶节点,它们是表达式的基本单元。
    • 通过这种方式,程序构建了一个抽象语法树 (AST),树的每个节点都是一个 Factor。整个复杂的表达式可以被视为一个单一的、顶层的 Factor
  2. 延迟求值与规范化

    • 解析阶段只构建 AST,不做任何计算。
    • 求值阶段通过调用根节点的 toPoly() 方法触发。这个方法递归地将整个 AST 转换成一个统一的规范表示——Poly(多项式)。
    • Poly 类是整个设计的核心,它将任何复杂的表达式结构(无论包含多少函数、求导、嵌套)都“压平”成一个标准的“和的标准型”:Σ c_i * x^a_i * y^b_i * exp(P_i)。其中 P_i 本身也是一个 Poly,这优雅地处理了指数嵌套。
    • 所有运算(加、乘、求导)都在 Poly 这个规范化表示上进行,极大地简化了逻辑,避免了对复杂 AST 的直接操作。

2. 文字类图

下面是项目主要类及其关系的文本表示形式:

========================= 表达式抽象语法树 (AST - Composite Pattern) =========================

[接口] Factor
   + toPoly(xval: Poly, yval: Poly): Poly
      ^
      |____________________________________________________________________________________
      |                |               |              |                |                   |
   Expr             Number          Variable      ExprFactor        ExpFunc           SelectFactor
   - terms: List<Term>                            - expr: Expr      - factor: Factor    - left: Factor
   (自身也实现Factor)                               - exponent        - exp: BigInteger   - right: Factor
                                                                                        - thenBranch: Factor
                                                                                        - elseBranch: Factor
      |
      |-----------------------------------------------------------------------------------
      |                        |                     |
   DerivFactor              FuncCall         IndexedFuncCall
   - inner: Factor          - arg: Factor        - index: int
   - op: Op (DX, DY, GRAD)                       - arg: Factor

   * Term (项)
     - factors: List<Factor>
     (注意: Term 本身不实现 Factor,是 Expr 的一部分)

================================== 解析器 (Parser) =========================================

   MainClass --uses--> InputProcessor --uses--> Parser --uses--> Lexer
      |                     |                (构建 AST)         (生成 Token 流)
      |                     |
      |                     +----------uses---------> FunctionRegistry (存储函数定义)
      |
      +-----> Poly.fromX() / Poly.fromY() (创建初始代入值)

================================= 规范化表示 (Canonical Form) ===============================

   (AST 中所有 Factor) --evaluates to--> Poly
                                            - terms: HashMap<Mono, BigInteger>
                                            + add, multiply, pow, deriveByX, deriveByY
                                            ^
                                            |
                                            | contains
                                            |
                                          Mono
                                            - expX: BigInteger
                                            - expY: BigInteger
                                            - expPoly: Poly  <-- 完美的递归定义

=================================== 函数处理 (Function Handling) ==============================

   InputProcessor --writes--> FunctionRegistry <--reads-- (FuncCall | IndexedFuncCall)
                               - simpleFunc: Expr
                               - recursiveFunc: RecursiveFuncDef

   RecursiveFuncDef --evaluates--> Poly
   - f0: Expr
   - f1: Expr
   - g1: Factor, g2: Factor, ...

3. 各类设计考虑与评价

3.1. 核心抽象

  • Factor (接口)

    • 设计考虑:作为组合模式的顶层抽象,统一定义了所有表达式“因子”的行为。toPoly(xval, yval) 是其核心,xvalyval参数的设计是为了支持函数调用时的变量替换(例如 f(x+1),就是将 x 替换为 x+1 的多项式表示)。
    • 内聚性:高。只定义了一个核心职责:将自身转换为规范多项式。
    • 耦合性:低。它只依赖于 Poly 类,这是无法避免的,因为 Poly 是求值的目标形式。
  • Poly (多项式)

    • 设计考虑:项目的“瑞士军刀”。它不仅是表达式的最终求值结果,也是 exp() 函数的参数,还是求导、恒等性判断等高级操作的执行者。内部使用 HashMap<Mono, BigInteger> 来存储项(Mono)和其系数,天然地支持了同类项合并。
    • 内聚性:中高。所有方法都围绕“多项式”这一核心概念服务,包括算术运算、求导、比较和字符串化。功能非常强大且集中。
    • 耦合性:中等。依赖 Mono。它的 deriveByX/Y 方法体现了链式法则,result.add(new Poly(m, c).multiply(dp)) 这一行代码清晰地展现了其递归求导结构,但同时也造成了对自身的依赖。
  • Mono (单项式)

    • 设计考虑x^a * y^b * exp(P) 的原子表示。最巧妙的设计是其 expPoly 字段的类型是 Poly,这使得 exp(exp(x)) 这样的嵌套结构得以用递归的方式优雅定义,是整个规范化体系的基石。
    • 内聚性:高。所有功能(乘法、比较、哈希)都服务于单项式本身。
    • 耦合性:中等。因为它递归地持有一个 Poly 对象,形成了 Poly -> Mono -> Poly 的循环依赖,但这对于表达嵌套指数是必要且合理的设计。

3.2. AST 组件

  • Expr / Term

    • 设计考虑:经典的表达式树结构。ExprTerm 相加,TermFactor 相乘。它们通过 toPoly() 方法递归地将计算委托给子节点,并将结果进行累加或累乘。
    • 内聚性:高。职责清晰,Expr 负责加法,Term 负责乘法。
    • 耦合性Expr 依赖 TermTerm 依赖 Factor,这是组合模式中典型的、良性的层级耦合。
  • Variable / Number

    • 设计考虑:AST 的最底层叶节点,逻辑简单,将自身转换为最简单的 Poly 形式。
    • 内聚性:非常高。
    • 耦合性:低。
  • ExprFactor / ExpFunc

    • 设计考虑ExprFactor 处理带括号的表达式 (expr)^expExpFunc 处理指数函数 exp(factor)^exp。它们都是通过递归调用内部因子的 toPoly 方法,然后对返回的 Poly 对象执行 powexp 相关的构造。
    • 内聚性:高。职责单一。
    • 耦合性:低。仅依赖于其子 FactorPoly
  • DerivFactor / SelectFactor

    • 设计考虑:这两个类体现了将复杂逻辑封装在 Poly 中执行的优势。
      • DerivFactor: 不直接在 AST 上做复杂的求导,而是先把内部表达式 inner 转为 Poly,然后调用 Poly 封装好的 deriveByX/Y 方法。
      • SelectFactor: 同样,先把 AB 转为 Poly,然后通过 pa.add(pb.negate()).isZero() 来判断恒等性。
    • 内聚性:高。逻辑清晰,职责明确。
    • 耦合性:低。将复杂性成功地转移给了 Poly 类。

3.3. 函数与解析

  • Lexer / Parser

    • 设计考虑:经典的递归下降解析器。Lexer 负责将字符串变为 token 流,Parser 根据文法消耗 token 并构建 AST。Parser 的方法如 parseExpr, parseTerm, parseFactor 相互递归调用,完美匹配了表达式的递归结构。
    • 内聚性:高。Lexer 只管分词,Parser 只管语法。
    • 耦合性Parser 强依赖于 Lexer,这是解析器设计的标准模式,耦合是必然且合理的。
  • InputProcessor

    • 设计考虑:作为顶层协调者,负责处理多行输入,解析函数定义,并最终解析主表达式。它通过 FunctionRegistry 来注册函数,解耦了函数定义和函数调用的过程。
    • 内聚性:中等。它处理多种不同的输入块(非递推函数、递推函数、主表达式),逻辑略显复杂,但都围绕“处理输入”这一主题。
    • 耦合性:中等。作为协调者,它需要与 Scanner, Parser, Lexer, FunctionRegistry 等多个类交互。
  • FunctionRegistry / RecursiveFuncDef / FuncCall / IndexedFuncCall

    • 设计考虑:这一组类共同构成了一个完整的函数处理子系统。
      • FunctionRegistry: 使用静态类作为单例注册表,提供全局的函数定义访问点,实现了“定义”与“使用”的解耦。
      • FuncCall / IndexedFuncCall: 在 toPoly 方法中,从 FunctionRegistry 获取函数定义,然后执行替换求值。
      • RecursiveFuncDef: 将递推函数的复杂逻辑(基例、递推式、参数)封装在一个对象中,evaluate 方法清晰地实现了递归展开。
    • 内聚性:高。每个类的职责都非常明确。
    • 耦合性FuncCallIndexedFuncCall 依赖 FunctionRegistry,这是典型的“服务定位器”模式带来的耦合,对于此场景是合适的。

4. 总体优缺点评价

优点

  1. 架构清晰,易于扩展:基于组合模式和规范化表示 (Poly) 的架构非常成功。当需要添加新的因子(例如 sin(x))时,只需:

    • 创建一个新的 SinFactor 类实现 Factor 接口。
    • Parser 中添加相应的解析逻辑。
    • PolyMono 中添加对 sin 的表示和求导/运算法则。
      整个系统的其他部分基本不受影响。
  2. **关注点分离 (SoC)**:

    • 解析与求值分离ParserLexer 专注于构建 AST,而 toPoly 方法和 Poly 类专注于计算。
    • 逻辑与表示分离:复杂的运算逻辑(如求导、恒等判断)被封装在规范的 Poly 类中,而不是散落在各个 AST 节点的类里。这使得逻辑的实现和维护更加简单。
    • 函数定义与调用分离FunctionRegistry 作为中间人,让解析器可以先定义函数,而调用处无需知道函数来自何处。

缺点与改进空间

  1. Parser 类过于庞大Parser 类承担了所有因子的解析任务,包括非递推/递推函数的特殊解析。虽然功能内聚,但代码量较大,可以考虑将某些复杂的解析逻辑(如 parseRecurrenceDef)提取到辅助类中,使 Parser 更专注于通用的表达式解析。

  2. 静态 FunctionRegistry 的限制:虽然 FunctionRegistry 实现了很好的解耦,但使用 static 字段使其成为一个全局单例。这在多线程环境下会产生问题(虽然本次作业是单线程),也不利于单元测试(测试之间会相互干扰,需要手动 reset())。可以考虑使用依赖注入的方式,将 FunctionRegistry 的实例传递给需要它的地方(如 Parser, FuncCall),从而避免全局状态。

  3. 性能优化Polypow 方法和 RecursiveFuncDefevaluate 方法都使用了递归/迭代,对于大指数或深的递归层级,可能会有性能问题。可以引入记忆化 (Memoization) 来缓存计算结果,例如在 RecursiveFuncDef.evaluate 中用一个 Map<Integer, Poly> 缓存 f{n}(arg) 的结果,避免重复计算。

面向对象程序设计——架构迭代分析报告

一、三次作业概览

维度第一次作业 (hw0)第二次作业 (hw2)第三次作业 (hw2_test2)
变量支持单变量 x单变量 x双变量 x, y
因子类型Number, Variable, ExprFactor+ExpFunc, FuncCall, SelectFactor+DerivFactor, IndexedFuncCall
多项式表示TreeMap<BigInteger, BigInteger>HashMap<Mono, BigInteger>HashMap<Mono, BigInteger>(Mono 扩展为二元)
函数支持简单自定义函数 f(x)简单函数 + 递归函数 f{n}(x)
求导支持dx, dy, grad 符号求导
条件表达式[A==B?C:D][A==B?C:D]
核心类数量101519

二、架构逐步成型过程

2.1 第一次作业:奠定基础框架

第一次作业构建了经典的三层架构,为后续迭代奠定了坚实的基础:

输入字符串 → Lexer(词法分析)→ Parser(语法分析)→ 表达式树 → toPoly()求值 → Poly → toString()输出

核心设计决策:

  1. Composite 模式的引入:定义 Factor 接口作为所有因子的统一抽象,NumberVariableExprFactor 均实现该接口。Expr 包含 List<Term>Term 包含 List<Factor>,形成递归的树形结构。

  2. 递归下降解析器Parser 通过 parseExpr()parseTerm()parseFactor() 的方法调用层次直接映射文法的优先级规则,结构清晰。

  3. 多项式统一表示:所有因子通过 toPoly() 方法转化为 Poly 对象,利用 TreeMap<BigInteger, BigInteger>(指数 → 系数)存储一元多项式,支持加法、乘法、快速幂运算。

类层次结构:

Factor (接口)
├── Number        (常数因子)
├── Variable      (变量 x^n)
└── ExprFactor    (括号表达式因子 (expr)^n)

Expr  → 包含 List<Term>
Term  → 包含 List<Factor>
Poly  → TreeMap<BigInteger, BigInteger>  // 指数 → 系数

此阶段架构简洁,职责分离清晰:Lexer 负责词法、Parser 负责语法、Factor 子类负责语义求值、Poly 负责多项式运算和输出格式化。


2.2 第二次作业:重大重构与功能扩展

第二次作业是架构变化最大的一次迭代,引入了指数函数 exp()、自定义函数 f(x) 和条件表达式 [A==B?C:D]这些新需求直接驱动了多项式表示层的重构

2.2.1 重构:多项式表示的根本性改变

重构原因: 第一次作业的 Poly 使用 TreeMap<BigInteger, BigInteger> 仅能表示形如 $\sum c_i x^{e_i}$ 的纯一元多项式。引入 exp() 后,表达式变为形如 $c \cdot x^a \cdot \exp(P(x))$ 的形式,旧的数据结构根本无法表达。

重构方案: 引入 Mono(单项式)类,将 Poly 的表示从 TreeMap<BigInteger, BigInteger> 重构为 HashMap<Mono, BigInteger>

对比项重构前 (hw0)重构后 (hw2)
多项式键BigInteger(x 的指数)Mono(含 expX 和 expPoly)
多项式值BigInteger(系数)BigInteger(系数)
单项式含义$c \cdot x^a$$c \cdot x^a \cdot \exp(P(x))$
容器类型TreeMap(有序)HashMap(需自定义 equals/hashCode)
合并同类项指数相同即合并Mono 的 expX 和 expPoly 均相同才合并

Mono 类的设计:

class Mono implements Comparable<Mono> {
    BigInteger expX;     // x 的指数
    Poly expPoly;        // exp() 内的多项式(可为空表示无 exp)

    // 单项式乘法:指数相加,exp 内多项式相加
    // (x^a * exp(P)) * (x^b * exp(Q)) = x^(a+b) * exp(P+Q)
    Mono multiply(Mono other);
}

这一重构是不可避免的结构性改变——旧的键类型(单个 BigInteger)在语义上不足以表达新的单项式结构。

2.2.2 新增因子类型

新增类作用实现方式
ExpFunc指数函数 exp(factor)^n利用 exp 幂律:$\exp(a)^n = \exp(n \cdot a)$
FuncCall自定义函数调用 f(arg)将参数求值后代入函数体(存储在 MainClass 静态字段)
SelectFactor条件表达式 [A==B?C:D]判断 A-B 是否为零多项式

2.2.3 toPoly() 接口的变化

// hw0: 无参
Poly toPoly();

// hw2: 传入 x 的实际多项式值(用于函数调用时的变量替换)
Poly toPoly(Poly xval);

这一变化使得函数调用的实参替换成为可能:调用 f(x+1) 时,将 xval = Poly(x+1) 传入函数体的 toPoly(xval),自然完成变量替换。

2.2.4 重构体验

这次重构的核心挑战在于 Poly 类几乎需要完全重写——数据结构从简单映射变为复杂的 Mono-Coefficient 映射,加法、乘法、toString() 等所有方法都需要适配新结构。但由于第一次作业建立了清晰的分层架构(Lexer → Parser → Factor → Poly),重构的影响被有效隔离在 Poly 层和 Factor.toPoly() 接口上,Parser 和 Lexer 几乎不受影响(仅需扩展新的 token 识别和 parseFactor 分支)。

这验证了良好的分层架构在面对需求变化时的抗风险能力:底层表示的剧变并未导致整个系统的崩塌。


2.3 第三次作业:平稳扩展

第三次作业的变化幅度明显小于第二次,主要是在已有架构上进行增量扩展,体现了重构后架构的良好可扩展性。

2.3.1 Mono 扩展为二元

// hw2 Mono
Mono(BigInteger expX, Poly expPoly)

// hw2_test2 Mono
Mono(BigInteger expX, BigInteger expY, Poly expPoly)

仅增加一个字段 expY,表示 $c \cdot x^a \cdot y^b \cdot \exp(P(x,y))$。这是对已有 Mono 结构的自然延伸,乘法规则同样自然扩展:指数分别相加。

2.3.2 Variable 扩展为多变量

// hw0/hw2: Variable 仅表示 x
Variable(BigInteger exponent)

// hw2_test2: Variable 区分 x 和 y
Variable(String name, BigInteger exponent)  // name = "x""y"

2.3.3 toPoly() 接口再次扩展

// hw2
Poly toPoly(Poly xval);

// hw2_test2
Poly toPoly(Poly xval, Poly yval);

所有 Factor 子类的 toPoly 签名统一变更,Variable 根据 name 选择返回 xval.pow(exp)yval.pow(exp)

2.3.4 新增功能模块

新增类作用
DerivFactor符号求导:dx(对x偏导)、dy(对y偏导)、grad(梯度)
IndexedFuncCall递归函数调用 f{k}(arg)
RecursiveFuncDef递归函数定义:$f{n} = c_1 f{n-1}(g_1) + c_2 f{n-2}(g_2) + \text{extra}$
FunctionRegistry函数注册中心,取代 hw2 中 MainClass 的静态字段

2.3.5 Poly 新增符号求导

Poly deriveByX();  // ∂P/∂x
Poly deriveByY();  // ∂P/∂y

对每个项 $c \cdot x^a \cdot y^b \cdot \exp(Q)$ 应用求导规则:

  • 幂规则:$c \cdot a \cdot x^{a-1} \cdot y^b \cdot \exp(Q)$
  • 链式法则(对 exp 部分):$c \cdot x^a \cdot y^b \cdot \exp(Q) \cdot \frac{\partial Q}{\partial x}$

这是在 Poly 类上的增量新增,不影响已有的加法、乘法等运算。

2.3.6 架构提升:FunctionRegistry 的抽取

第二次作业中,函数体直接存储在 MainClass.funcBody 静态字段中,FuncCall 直接引用 MainClass.getFuncBody()。第三次作业将其抽取为独立的 FunctionRegistry 类,管理简单函数和递归函数,降低了耦合。


三、重构分析总结

3.1 重构发生点

三次作业中,第一次到第二次之间发生了一次重大重构,核心变化集中在多项式表示层:

hw0 Poly: TreeMap<BigInteger, BigInteger>
              ↓ 重构(引入 Mono 类)
hw2 Poly: HashMap<Mono, BigInteger>
              ↓ 平稳扩展(Mono 增加 expY)
hw3 Poly: HashMap<Mono, BigInteger>  // Mono(expX, expY, expPoly)

3.2 重构影响范围

              hw0 → hw2 重构影响
─────────────────────────────────────────
 Lexer         (新增 token 类型)     
 Parser        (新增 parse 分支)     
 Factor 接口   (toPoly 增加参数)     
 各 Factor 类  (适配新 toPoly 签名)  
 Poly          (数据结构根本性变更)  
 Mono          (全新类)             
─────────────────────────────────────────

              hw2 → hw3 扩展影响
─────────────────────────────────────────
 Lexer        (新增 token 类型)    
 Parser       (新增 parse 分支)    
 Factor 接口  (toPoly 增加 yval)  
 Mono         (增加 expY 字段)     
 Poly         (新增求导方法)       
 新增类        DerivFactor 等 4 个新类    
─────────────────────────────────────────

3.3 重构体验

  1. 第一次重构(hw0→hw2)的痛点:Poly 的数据结构是整个系统的"地基",改动它意味着所有依赖 Poly 的代码(即几乎所有 Factor 类的 toPoly 实现、toString 输出逻辑)都需要联动修改。但因为 Factor 接口的统一抽象,新增的 Factor 类型(ExpFunc、FuncCall、SelectFactor)可以自然地融入现有框架——只需实现 toPoly() 即可。

  2. 第二次扩展(hw2→hw3)的顺畅:得益于重构后 Mono+Poly 的灵活表示,引入第二个变量 y 只需在 Mono 中新增一个字段,求导功能也只是在 Poly 上新增方法。新的 Factor 类型(DerivFactor、IndexedFuncCall)同样只需实现接口即可接入系统。架构已经"成型",扩展变得轻松。


四、架构演进图

第一次作业 (hw0)                    第二次作业 (hw2)                    第三次作业 (hw2_test2)
─────────────────                  ─────────────────                  ─────────────────────
      MainClass                          MainClass                          MainClass
         │                                  │                                  │
      Parser ← Lexer                  InputProcessor                    InputProcessor
         │                              │        │                      │        │
      parseExpr/Term/Factor        Parser ← Lexer                 Parser ← Lexer
         │                              │                               │
   ┌─────┴─────┐                 ┌──────┴──────┐                ┌──────┴──────────┐
   Expr    Term                  Expr      Term                 Expr          Term
   │       │                     │         │                    │              │
   Factor(接口)                  Factor(接口)                   Factor(接口)
   ├─ Number                     ├─ Number                      ├─ Number
   ├─ Variable                   ├─ Variable                    ├─ Variable(x/y)
   ├─ ExprFactor                 ├─ ExprFactor                  ├─ ExprFactor
   │                             ├─ ExpFunc           新增      ├─ ExpFunc
   │                             ├─ FuncCall          新增      ├─ FuncCall
   │                             ├─ SelectFactor      新增      ├─ SelectFactor
   │                             │                              ├─ DerivFactor       新增
   │                             │                              ├─ IndexedFuncCall   新增
   │                             │                              │
   Poly                          Poly ← Mono         重构      Poly ← Mono(含y)    扩展
   (TreeMap)                     (HashMap<Mono,BI>)             (+deriveByX/Y)
                                                                FunctionRegistry     新增
                                                                RecursiveFuncDef     新增

五、自定义迭代情景:新增三角函数支持

5.1 需求描述

假设第四次作业要求新增 sin(factor)cos(factor) 的支持,表达式可包含形如 $c \cdot x^a \cdot y^b \cdot \sin(P)^m \cdot \cos(Q)^n \cdot \exp(R)$ 的项。

5.2 基于当前架构的扩展方案

1. Mono 层扩展

class Mono {
    BigInteger expX, expY;
    Poly expPoly;           // exp() 内多项式(已有)
    // 新增:
    Map<Poly, BigInteger> sinTerms;  // sin(P)^m
    Map<Poly, BigInteger> cosTerms;  // cos(Q)^n
}

Mono 的 multiply()equals()hashCode()compareTo() 需相应扩展,但这是局部改动。

2. 新增 Factor 子类

class SinFunc implements Factor {
    Factor inner;
    BigInteger exponent;
    Poly toPoly(Poly xval, Poly yval) { ... }
}
class CosFunc implements Factor { /* 类似 */ }

这与 ExpFunc 的实现方式完全类似,只需实现 Factor 接口即可无缝接入。

3. Parser 扩展

parseFactor() 中新增 "sin""cos" 的分支,逻辑与 parseExpFunc() 类似。Lexer 新增 "sin""cos" token 识别。

4. Poly 求导扩展

需在 deriveByX()/deriveByY() 中增加三角函数的链式法则。

5.3 可扩展性评估

评估维度结论
新增类数量2 个 Factor 子类(SinFunc、CosFunc)
已有类修改Mono(增加字段)、Poly(求导规则)、Parser/Lexer(新语法)
架构变动无需改变架构,所有改动都是在已有框架内的增量扩展
风险等级低——Mono 扩展虽涉及 equals/hashCode,但模式与 expPoly 完全一致

当前架构的 Factor 接口 + Mono/Poly 表示 组合提供了良好的扩展点:新的数学函数只需实现 Factor 接口并在 Mono 中增加对应的指数字段即可。这正是 Composite 模式和统一求值接口 toPoly() 带来的设计红利。


六、总结

三次作业的架构演进路径清晰:

  1. hw0 打基础:确立了 Lexer → Parser → Factor(Composite) → Poly 的分层架构和递归下降解析范式。
  2. hw2 做重构:为适配 exp() 函数,对 Poly 层进行了结构性重构(引入 Mono),同时扩展了 Factor 接口的参数签名以支持变量替换。
  3. hw3 稳扩展:在重构后的架构上平稳新增二元变量、符号求导、递归函数等功能,验证了架构的可扩展性。

整体来看,第一次作业的 分层设计Factor 接口抽象 是架构长期健壮的关键;第二次作业的 Mono 重构 虽然痛苦但为后续扩展打下了良好基础;第三次作业的平稳扩展则验证了这一架构决策的正确性。

BUG分析

代码一般通过借助AI给出的数据点来进行测试,主要通过数据大小以及边界情况来进行分析和针对性测试,对于互测中被hack到的数据点,进行针对性的模块和对应路径分析,得益于代码的架构和职责单一使得bug在某一条链路中较为容易找到。

优化

没有使用优化,以至于性能分一直以来都较差。

大模型

  • 在正确性使用上达到了将近50%,通过和AI探讨题目内容和任务要求来形成初始架构,然后和AI 进一步交流决定设计多少个类以及要实现的方法,最后填入细节和内容。
  • 在测试AI代码的能力的时候,借助AI 生成一些较为刁钻的数据来帮助测试代码。
  • 不知道同学的代码是否大量使用了AI生成的代码

心得体会

最深刻的是在研讨课上与老师和组员们的交流产生的思想碰撞和感受。
归一化的处理思想体现在预处理中的时候,我触碰到了自己思维的盲区,让每一个模块在分工明确中,各自处理好自己的事情,而不是全部包揽给某一个模块。
同样是使用大模型,不同的人有不同的用法,有的人用大模型来解放自己的大脑,有的人用大模型来解放自己的双手。

未来方向

更多的注重思路和想法的展现,而不是细节的实现吧。

...全文
139 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

309

社区成员

发帖
与我相关
我的任务
社区描述
2026年北航面向对象设计与构造
java 高校
社区管理员
  • 孙琦航
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧