# DataCollect 教学项目 — 最小可运行版本 这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。 构建: ```bash mvn -q package ``` 运行(示例): ```bash java -jar target/datacollect-cli-0.1.0-jar-with-dependencies.jar --help ``` 项目结构(最小): - `src/main/java/com/example/datacollect/Main.java` — CLI 入口,打印帮助 - `pom.xml` — Maven 构建配置,生成可执行 jar --- ## MVC架构越权审计报告 ### 架构概览 ``` View (ConsoleView) ← 直接访问 → Model (Article) ↑ ↑ └──── Controller ────────┘ (CrawlerController + Command) ``` ### 发现的问题 #### 1. View越权访问Model (严重) **位置**: `ConsoleView.java` 第32-41行 ```java public void display(List
articles) { ... System.out.println((i + 1) + ". " + a.getTitle() + " | " + a.getUrl()); } ``` **问题**: `ConsoleView.display()` 接收原始 `List
` 并直接访问其内部字段。View层不应该知道Model的数据结构。 #### 2. Controller → Model 直接传递 (严重) **位置**: `ListCommand.java` 第20行 ```java public void execute(String[] args, List
articles) { view.display(articles); // 直接传递原始Model对象 } ``` **问题**: Controller应该将Model转换为View可用的DTO/VO,而不是直接传递Model对象。 #### 3. Command接口设计缺陷 (中等) **位置**: `Command.java` ```java public interface Command { String getName(); void execute(String[] args, List
articles); // 直接暴露Model } ``` **问题**: `Command.execute()` 直接接收 `List
`,导致所有Command都可以直接操作Model数据。 #### 4. HistoryCommand直接操作业务数据 (中等) **位置**: `HistoryCommand.java` ```java public class HistoryCommand implements Command { private final List commandHistory; // 业务状态不应该在Command中 ... } ``` **问题**: `commandHistory` 是业务层数据,不应由Command类持有。Controller直接传递了自己的内部状态给Command。 ### 正确的MVC数据流向 ``` 用户输入 → Controller → Model(业务逻辑) → DTO/VO → View(展示) ↓ Command(命令解析,不直接操作Model) ``` ### 修复建议 | 问题 | 当前做法 | 正确做法 | |------|---------|---------| | View访问Model | `view.display(articles)` 直接用Article | Controller转换为 `List` lines | | ListCommand | 直接传Article列表 | Controller转换为展示数据 | | Command接口 | 暴露 `List
` | 改为传 `Map` context | ### 风险评估 | 越权类型 | 严重程度 | 影响 | |---------|---------|------| | View访问Model内部结构 | ⚠️ 高 | View与Model耦合,Model变更影响View | | Controller直接传递Model | ⚠️ 高 | 业务逻辑分散在Command中,难以维护 | | Command持有业务状态 | 🟡 中 | 违反单一职责,测试困难 |