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.
344 lines
36 KiB
344 lines
36 KiB
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ 大宗商品数据爬虫与可视化分析系统 - UML类图 │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
一、命令模式 (Command Pattern)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌──────────────────────┐
|
|
│ <<interface>> │
|
|
│ Command │
|
|
├──────────────────────┤
|
|
│ + execute() │
|
|
│ + getName() │
|
|
│ + getDescription() │
|
|
│ + isUndoable() │
|
|
│ + undo() │
|
|
└──────────┬───────────┘
|
|
│
|
|
┌──────────────┬───────────────┼───────────────┬──────────────┬───────────────┬──────────────┐
|
|
│ │ │ │ │ │ │
|
|
▼ ▼ ▼ ▼ ▼ ▼ ▼
|
|
┌──────────────────┐ ┌────────────┐ ┌───────────┐ ┌───────────────┐ ┌────────────┐ ┌───────────┐ ┌───────────┐
|
|
│ CrawlCommand │ │ExportData │ │Generate │ │ GenerateReport│ │ Monitor │ │ ViewData │ │ExitCommand│
|
|
│ │ │ Command │ │ChartCommand│ │ Command │ │ Command │ │ Command │ │ │
|
|
├──────────────────┤ ├───────────┤ ├───────────┤ ├───────────────┤ ├────────────┤ ├───────────┤ ├───────────┤
|
|
│-controller │ │-format │ │ │ │ │ │-broadcaster│ │-indexRepo │ │ │
|
|
│-site │ │-controller│ │ │ │ │ │ │ │-marketRepo│ │ │
|
|
│-pageCount │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
│-savedCount │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
├──────────────────┤ ├───────────┤ ├───────────┤ ├───────────────┤ ├────────────┤ ├───────────┤ ├───────────┤
|
|
│+execute() │ │+execute() │ │+execute() │ │+execute() │ │+execute() │ │+execute() │ │+execute() │
|
|
│+getName() │ │+getName() │ │+getName() │ │+getName() │ │+getName() │ │+getName() │ │+getName() │
|
|
│+getDescription() │ │+getDesc() │ │+getDesc() │ │+getDescription │ │+getDesc() │ │+getDesc() │ │+getDesc() │
|
|
└──────────────────┘ └───────────┘ └───────────┘ └───────────────┘ └────────────┘ └───────────┘ └───────────┘
|
|
│ │ │ │ │ │ │
|
|
└──────────────────┴────────────┴──────────────┴────────────────┴──────────────┴──────────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────────┐
|
|
│ CommandInvoker │
|
|
├────────────────────────────┤
|
|
│ - commandMap │
|
|
│ - commandHistory │
|
|
├────────────────────────────┤
|
|
│ + registerCommand(key,cmd) │
|
|
│ + executeCommand(key) │
|
|
│ + undo() │
|
|
└────────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
二、策略模式 (Strategy Pattern)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌──────────────────────────────┐
|
|
│ <<interface>> │
|
|
│ CrawlStrategy │
|
|
├──────────────────────────────┤
|
|
│ + crawlData(pageCount) │
|
|
│ + saveData(dataList) │
|
|
│ + getSiteName() │
|
|
└──────────────┬───────────────┘
|
|
│
|
|
┌────────────────────────────┬┴─────────────────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌────────────────────────────────┐ ┌────────────────────────────────┐ ┌────────────────────────────────┐
|
|
│ JinTouCrawlStrategy │ │ EastMoneyCrawlStrategy │ │ TongHuaShunCrawlStrategy │
|
|
│ (金投网) │ │ (东方财富网) │ │ (同花顺) │
|
|
├────────────────────────────────┤ ├────────────────────────────────┤ ├────────────────────────────────┤
|
|
│ - repository : MarketDataRepo │ │ - repository : IndexDataRepo │ │ - repository : NewsDataRepo │
|
|
├────────────────────────────────┤ ├────────────────────────────────┤ ├────────────────────────────────┤
|
|
│ + crawlData(pageCount) │ │ + crawlData(pageCount) │ │ + crawlData(pageCount) │
|
|
│ + saveData(dataList) │ │ + saveData(dataList) │ │ + saveData(dataList) │
|
|
│ + getSiteName() : "金投网" │ │ + getSiteName() : "东方财富网" │ │ + getSiteName() : "同花顺财经" │
|
|
└────────────────────────────────┘ └────────────────────────────────┘ └────────────────────────────────┘
|
|
│ │ │
|
|
└────────────────────────────┴───────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────┐
|
|
│ CrawlStrategyFactory │
|
|
├─────────────────────────────────┤
|
|
│ + createStrategy(siteCode) │
|
|
│ : CrawlStrategy │
|
|
└─────────────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
三、模型类 (Model Classes)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌─────────────────────────────────┐ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐
|
|
│ MarketData │ │ IndexData │ │ NewsData │
|
|
│ 行情数据 │ │ 指数数据 │ │ 舆情数据 │
|
|
├─────────────────────────────────┤ ├─────────────────────────────────┤ ├─────────────────────────────────┤
|
|
│ - id : Long │ │ - id : Long │ │ - id : Long │
|
|
│ - variety : String │ │ - indexName : String │ │ - title : String │
|
|
│ - tradeDate : Date │ │ - date : Date │ │ - content : String │
|
|
│ - openPrice : BigDecimal │ │ - indexValue : BigDecimal │ │ - publishTime : Date │
|
|
│ - closePrice : BigDecimal │ │ - changeRate : BigDecimal │ │ - relatedCommodity : String │
|
|
│ - highPrice : BigDecimal │ │ - stockName : String │ │ - sentiment : String │
|
|
│ - lowPrice : BigDecimal │ │ - stockPrice : BigDecimal │ │ - createTime : Date │
|
|
│ - volume : BigDecimal │ │ - turnoverRate : BigDecimal │ │ - source : String │
|
|
│ - changeRate : BigDecimal │ │ - createTime : Date │ └─────────────────────────────────┘
|
|
│ - createTime : Date │ │ - source : String │
|
|
│ - source : String │ └─────────────────────────────────┘
|
|
└─────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────┐
|
|
│ PriceSnapshot │
|
|
│ 价格快照 │
|
|
├─────────────────────────────────┤
|
|
│ - commodityName : String │
|
|
│ - currentPrice : double │
|
|
│ - changePercent : double │
|
|
│ - timestamp : long │
|
|
└─────────────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
四、仓储层 (Repository Layer)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌──────────────────────────────────────┐ ┌──────────────────────────────────────┐ ┌──────────────────────────────────────┐
|
|
│ MarketDataRepository │ │ IndexDataRepository │ │ NewsDataRepository │
|
|
│ 市场数据仓储 │ │ 指数数据仓储 │ │ 舆情数据仓储 │
|
|
├──────────────────────────────────────┤ ├──────────────────────────────────────┤ ├──────────────────────────────────────┤
|
|
│ - sqlSessionFactory │ │ - sqlSessionFactory │ │ - sqlSessionFactory │
|
|
├──────────────────────────────────────┤ ├──────────────────────────────────────┤ ├──────────────────────────────────────┤
|
|
│ + save(data) : int │ │ + save(data) : int │ │ + save(data) : int │
|
|
│ + batchSave(dataList) : int │ │ + batchSave(dataList) : int │ │ + batchSave(dataList) : int │
|
|
│ + findAll() : List~MarketData~ │ │ + findAll() : List~IndexData~ │ │ + findAll() : List~NewsData~ │
|
|
│ + findByVariety(variety) │ │ + findByIndexName(indexName) │ │ + findByCommodity(commodity) │
|
|
│ + count() : int │ │ + count() : int │ │ + count() : int │
|
|
└──────────────────────────────────────┘ └──────────────────────────────────────┘ └──────────────────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
五、工具类 (Utility Classes)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌──────────────────────────────────────┐ ┌──────────────────────────────────────┐
|
|
│ ChartGenerator │ │ PdfReportGenerator │
|
|
│ 图表生成器 │ │ PDF报告生成器 │
|
|
├──────────────────────────────────────┤ ├──────────────────────────────────────┤
|
|
│ + generatePriceTrendChart() │ │ - chineseFont : PDType0Font │
|
|
│ + generateVolatilityChart() │ ├──────────────────────────────────────┤
|
|
│ + generateCorrelationChart() │ │ + generateReport() │
|
|
│ + generateSentimentChart() │ │ + generateCoverPage() │
|
|
└──────────────────────────────────────┘ │ + generateDataTable() │
|
|
└──────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────┐
|
|
│ <<interface>> │
|
|
│ DataExporter │
|
|
├──────────────────────────────────────┤
|
|
│ + export(data, outputPath) │
|
|
│ + getFormat() : String │
|
|
│ + getFileExtension() : String │
|
|
└──────────────┬───────────────────────┘
|
|
│
|
|
┌────────────────────────────┴────────────────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
│ ExcelExporter │ │ CsvExporter │ │ JsonExporter │
|
|
├───────────────┤ ├───────────────┤ ├───────────────┤
|
|
│ + export() │ │ + export() │ │ + export() │
|
|
│ + getFormat() │ │ + getFormat() │ │ + getFormat() │
|
|
└───────────────┘ └───────────────┘ └───────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ DataExporterFactory │
|
|
├───────────────────────────┤
|
|
│ + createExporter(format) │
|
|
└───────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
六、监控模块 (Monitor Module)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌──────────────────────────────────────┐
|
|
│ DataBroadcaster │
|
|
│ 数据广播器 │
|
|
├──────────────────────────────────────┤
|
|
│ - serverSocket : ServerSocket │
|
|
│ - connections : Map~WebSocket,~ │
|
|
│ - scheduler : ScheduledExecutorService│
|
|
├──────────────────────────────────────┤
|
|
│ + start(port) │
|
|
│ + stop() │
|
|
│ + broadcast(message) │
|
|
│ + onOpen(ws, handshake) │
|
|
│ + onClose(ws, code, reason) │
|
|
│ + onMessage(ws, message) │
|
|
└──────────────────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
七、异常类层次 (Exception Hierarchy)
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌─────────────────────────────────────────────┐
|
|
│ BaseCrawlException │
|
|
│ (爬虫异常基类) │
|
|
├─────────────────────────────────────────────┤
|
|
│ - errorCode : String │
|
|
│ - errorMessage : String │
|
|
│ - cause : Throwable │
|
|
└──────────────────────┬──────────────────────┘
|
|
│
|
|
┌──────────────────────────────┬┴───────────────────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌─────────────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────┐
|
|
│ NetworkException │ │ ParseException │ │ DbException │
|
|
│ (网络异常) │ │ (解析异常) │ │ (数据库异常) │
|
|
├─────────────────────────┤ ├─────────────────────────┤ ├─────────────────────────┤
|
|
│ 支持重试机制 │ │ 网页解析失败 │ │ SQL执行失败 │
|
|
└─────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ ParamException │
|
|
│ (参数异常) │
|
|
├─────────────────────────┤
|
|
│ 参数校验失败 │
|
|
└─────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
八、核心调用关系
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌─────────────────┐
|
|
│ InteractiveCLI │ ◄────── 程序入口
|
|
└────────┬────────┘
|
|
│ uses
|
|
▼
|
|
┌─────────────────┐
|
|
│ CommandInvoker │ ◄────── 命令调用者
|
|
└────────┬────────┘
|
|
│ executes
|
|
▼
|
|
┌─────────────────┐ uses ┌─────────────────────────┐
|
|
│ CrawlCommand │──────────────────►│ CrawlerController │
|
|
└─────────────────┘ └───────────┬─────────────┘
|
|
│ uses
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ CrawlStrategyFactory │
|
|
└─────────────┬─────────────┘
|
|
│ creates
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ CrawlStrategy │
|
|
│ (接口) │
|
|
└─────────────┬─────────────┘
|
|
│
|
|
┌────────────────────────┬┴────────────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
|
│ JinTouCrawl │ │ EastMoneyCrawl │ │TongHuaShunCrawl │
|
|
│ Strategy │ │ Strategy │ │ Strategy │
|
|
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
|
│MarketDataRepository│ │IndexDataRepository│ │NewsDataRepository│
|
|
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
|
|
│ │ │
|
|
└──────────────────────┴──────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ SQLite Database │
|
|
│ (MyBatis) │
|
|
└─────────────────────────┘
|
|
|
|
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
图例
|
|
═══════════════════════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
┌─────────────┐
|
|
│ Class │ 类
|
|
├─────────────┤
|
|
│ - field │ -: private
|
|
│ + method() │ +: public
|
|
└─────────────┘
|
|
|
|
┌─────────────────────┐
|
|
│ <<interface>> │ 接口
|
|
│ Interface │
|
|
└─────────────────────┘
|
|
|
|
│ │
|
|
│ implements │ 实现关系
|
|
▼ │
|
|
┌─────────┐ │
|
|
│ Concrete│ │
|
|
└─────────┘ │
|
|
|
|
│ │
|
|
◄─────────────── │ 依赖关系
|
|
│
|
|
▼
|
|
|
|
┌───┐ ┌───┐
|
|
│ A │────►│ B │ 关联关系
|
|
└───┘ └───┘
|
|
|
|
┌───┐ ┌───┐
|
|
│ A │◄───►│ B │ 双向关联
|
|
└───┘ └───┘
|
|
|
|
┌───┐
|
|
│ A │─────│ 聚合关系 (空心菱形)
|
|
└───┘ │
|
|
▼
|
|
┌─────┐
|
|
│ B │
|
|
└─────┘
|
|
|
|
┌───┐
|
|
│ A │─────◆ 组合关系 (实心菱形)
|
|
└───┘
|
|
│
|
|
▼
|
|
┌─────┐
|
|
│ B │
|
|
└─────┘
|
|
|
|
──────────────► 依赖/使用关系
|
|
|
|
──────────────▶ 指向
|
|
|
|
@enduml
|
|
|