You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
1 month ago | |
|---|---|---|
| .. | ||
| command | 1 month ago | |
| controller | 1 month ago | |
| model | 1 month ago | |
| service | 1 month ago | |
| src/main/java/com/example/datacollect | 1 month ago | |
| target | 1 month ago | |
| view | 1 month ago | |
| .gitignore | 1 month ago | |
| Main.java | 1 month ago | |
| README.md | 1 month ago | |
| pom.xml | 1 month ago | |
README.md
DataCollect 教学项目 — 最小可运行版本
这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。
构建:
mvn -q package
运行(示例):
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 这是一个非常完整的 Java CLI 应用从“可用”到“健壮”的演进过程。我们将整个过程总结为 5 个核心阶段,涵盖了架构设计、代码重构、功能扩展、用户体验优化以及设计原则的落地。
整个优化流程总结
1. 初始阶段:MVC + 命令模式架构搭建
目标:让程序跑起来,结构清晰。
- 架构:采用 MVC (Model-View-Controller) 结合 命令模式 (Command Pattern)。
- 核心类:
Model:Article(数据实体)。View:ConsoleView(输入输出,颜色美化)。Controller:CrawlerController(命令分发)。Command:Command接口 + 具体实现 (CrawlCommand,ListCommand等)。
- 数据流:用户输入 → Controller 解析 → 调用 Command → 操作数据 → 输出结果。
- 状态:✅ 功能可用,✅ 结构清晰,❌ 耦合度高,❌ 扩展性差。
2. 重构阶段:引入 DataService 解耦
目标:解决 Command 直接依赖 List 的问题,实现依赖倒置。
- 痛点:原代码中
Command直接持有List<Article>,如果未来要存数据库或文件,所有命令都要改。 - 优化:
- 新增
DataService接口(定义save,get,remove等方法)。 - 实现
ArticleRepository类实现DataService。 - 修改
Command接口:参数从List<Article>改为DataService。 - 修改
Controller:注入DataService而非List。
- 新增
- 收益:✅ 开闭原则(新增存储方式无需改命令),✅ 易于测试(可 Mock
DataService)。
3. 功能扩展阶段:完善 CRUD 与持久化
目标:让应用真正具备生产力,不仅仅是演示。
- 新增命令:
SearchCommand:支持关键词搜索(查)。DeleteCommand:支持按索引删除(改)。SaveCommand/LoadCommand:支持文件读写(持久化)。
- 数据完整性:确保
CrawlCommand真正将数据存入DataService,而非仅打印日志。 - 收益:✅ 功能闭环(增删改查全),✅ 数据安全(重启不丢失)。
4. 体验优化阶段:增强交互与容错
目标:提升用户命令行体验,减少错误操作。
ListCommand优化:- 增加
limit参数(如list 10),防止刷屏。 - 增加分页提示(“显示前 20 条,共 50 条”)。
- 增加空列表友好提示。
- 增加
- 参数校验:所有命令增加参数数量检查(如
crawl必须带 URL)。 - 异常处理:增加
try-catch处理文件 IO 异常和数字格式异常。 - 收益:✅ 用户体验好(防刷屏、提示清晰),✅ 健壮性强(不轻易崩溃)。
5. 最终架构:标准化与最佳实践
目标:形成可维护、可扩展的企业级 CLI 雏形。
- 包结构:
src/ ├── model/ (Article, DataService, ArticleRepository) ├── command/ (Command 接口,所有具体命令) ├── controller/ (CrawlerController) ├── view/ (ConsoleView) └── Main.java (入口) - 设计原则:
- 单一职责:每个类只做一件事。
- 依赖倒置:依赖接口
DataService而非具体List。 - 开闭原则:新增命令只需实现
Command接口,无需修改Controller。
📊 优化前后对比表
| 维度 | 优化前 (V1) | 优化后 (V2) |
|---|---|---|
| 数据依赖 | Command 直接依赖 List<Article> |
Command 依赖 DataService 接口 |
| 数据持久化 | ❌ 内存数据,重启丢失 | ✅ 支持 save/load 到文件 |
| 查询能力 | ❌ 仅能列出全部 | ✅ 支持 search 关键词筛选 |
| 管理能力 | ❌ 无法删除 | ✅ 支持 delete 按索引删除 |
| 列表显示 | ❌ 全部显示,可能刷屏 | ✅ 支持 list <num> 分页显示 |
| 错误处理 | ❌ 简单打印,易崩溃 | ✅ 参数校验,异常捕获 |
| 扩展性 | ❌ 新增功能需改多处 | ✅ 新增命令无需改 Controller |
🛠️ 核心代码变化速览
-
接口定义变化:
// 旧 void execute(String[] args, List<Article> articles); // 新 void execute(String[] args, DataService dataService); -
控制器注入变化:
// 旧 public CrawlerController(ConsoleView view, List<Article> articles) // 新 public CrawlerController(ConsoleView view, DataService dataService) -
视图方法变化:
// 旧 void display(List<Article> articles) // 新 void display(List<Article> articles, int totalSize)
🎓 设计原则总结
在这个优化过程中,我们实际上实践了以下 SOLID 原则:
- S (Single Responsibility):
ConsoleView只管显示,DataService只管数据,Command只管逻辑。 - O (Open/Closed):新增
DeleteCommand时,不需要修改CrawlerController的handle方法。 - L (Liskov Substitution):任何实现
DataService的类(如FileService,DBService)都可以替换ArticleRepository。 - I (Interface Segregation):
DataService接口只定义了必要的数据操作方法,没有混杂 UI 逻辑。 - D (Dependency Inversion):高层模块 (
Controller,Command) 依赖抽象 (DataService),而非具体实现 (ArrayList)。