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.
 
 
 
ZhengJiayin 3d34bb3ed1 w10 1 month ago
..
command w10 1 month ago
controller w10 1 month ago
model w10 1 month ago
repository w10 1 month ago
strategy w10 1 month ago
view w10 1 month ago
Main.java w10 1 month ago
README.md w10 1 month ago

README.md

W10 作业提交:设计模式实战

目录结构

w10/
└── src/
    └── main/
        └── java/
            └── com/
                └── example/
                    └── datacollect/
                        ├── Main.java
                        ├── command/
                        │   ├── Command.java
                        │   ├── CrawlCommand.java
                        │   ├── AnalyzeCommand.java
                        │   ├── ListCommand.java
                        │   ├── HelpCommand.java
                        │   ├── ExitCommand.java
                        │   └── HistoryCommand.java
                        ├── controller/
                        │   └── CrawlerController.java
                        ├── model/
                        │   └── Article.java
                        ├── repository/
                        │   └── ArticleRepository.java
                        ├── strategy/
                        │   ├── CrawlStrategy.java
                        │   ├── StrategyFactory.java
                        │   ├── HnuNewsStrategy.java
                        │   ├── BlogStrategy.java
                        │   ├── NewsStrategy.java
                        │   └── GenericNewsStrategy.java
                        └── view/
                            └── ConsoleView.java

必做任务完成情况

1. ArticleRepository 完善

  • add(): 拒绝 null,抛出 IllegalArgumentException
  • addAll(): 拒绝 null 列表和列表中的 null 元素
  • getAll(): 返回 Collections.unmodifiableList() 不可变视图
  • size(): 返回文章数量
  • clear(): 清空所有文章

2. AnalyzeCommand

  • 复用策略解析但不存储到 Repository
  • 输出统计信息:文章总数、含作者/日期/内容的数量、使用的策略名称
  • 显示前 3 篇文章标题作为预览

3. AI 架构审计

类签名汇总

// Command 层
interface Command { void execute(String[], ArticleRepository); }
class CrawlCommand(ConsoleView, StrategyFactory)
class AnalyzeCommand(ConsoleView, StrategyFactory)
class ListCommand(ConsoleView)
class HelpCommand(ConsoleView)
class ExitCommand(ConsoleView)
class HistoryCommand(ConsoleView, List<String>)

// Controller 层
class CrawlerController(ConsoleView, ArticleRepository, StrategyFactory)

// Repository 层
class ArticleRepository { add(), addAll(), getAll(), size(), clear() }

// Strategy 层  
interface CrawlStrategy { parse(), supports(), getPriority(), getPattern() }
class StrategyFactory { getStrategy(url), register(), setDefaultStrategy() }
class HnuNewsStrategy implements CrawlStrategy
class BlogStrategy implements CrawlStrategy
class NewsStrategy implements CrawlStrategy
class GenericNewsStrategy implements CrawlStrategy (正则匹配)

// Model 层
class Article { title, url, content, author, publishDate }

// View 层
class ConsoleView

架构审计结果

检查项 结果 说明
策略解耦 优秀 策略接口与实现完全分离
Repository 封装 优秀 使用不可变视图 + null 防御
开闭原则 达标 新增网站只需加策略类 + 注册一行
依赖倒置 良好 Command/Strategy 依赖抽象接口
单一职责 达标 每个类职责清晰
循环依赖 依赖链单向

选做任务完成情况

正则策略匹配

  • GenericNewsStrategy 使用正则表达式 .*\.(news|press|article)s?\..* 匹配新闻类网站

默认策略

  • StrategyFactory 内置 DefaultStrategy,当没有匹配策略时返回空列表

策略优先级

  • CrawlStrategy 接口新增 getPriority() 默认方法
  • GenericNewsStrategy 设置优先级为 5(高于默认优先级 1)
  • StrategyFactory.getStrategy() 遍历所有策略,选择优先级最高的匹配策略

思考题答案

Q: 两个策略都 supports 同一 URL 时怎么办?

A: 采用优先级机制解决:

  1. 每个策略实现可以通过 getPriority() 返回优先级值
  2. StrategyFactory.getStrategy() 遍历所有策略时,记录最高优先级
  3. 如果多个策略都支持同一 URL,选择优先级最高的那个
  4. 如果优先级相同,选择最先注册的策略(遍历顺序决定)

这种设计的优势:

  • 允许通用策略(如 GenericNewsStrategy)和专用策略(如 HnuNewsStrategy)共存
  • 专用策略可设置更高优先级,确保精确匹配优先
  • 通用策略作为兜底,提高系统兼容性

命令功能对比

命令 功能 是否存储
crawl <url> 爬取并存储文章
analyze <url> 分析文章统计(不存储)
list 列出已存储文章 -
history 显示命令历史 -
help 显示帮助 -
exit 退出程序 -

设计模式应用

  1. 策略模式CrawlStrategy 接口定义标准,各策略独立实现
  2. 工厂模式StrategyFactory 根据 URL 自动选择策略
  3. Repository 模式:数据访问封装,防御式编程
  4. 命令模式:所有 Command 统一签名,易于扩展