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.

300 lines
7.9 KiB

@startuml大宗商品爬虫系统类图
title 大宗商品数据爬虫与可视化分析系统 - 类图
skinparam backgroundColor #FEFEFE
skinparam classAttributeIconSize 0
' ========== 命令模式 ==========
package "command <<命令模式>>" #LightBlue {
interface Command {
+ execute()
+ getName() : String
+ getDescription() : String
+ isUndoable() : boolean
+ undo()
}
class CommandInvoker {
- commandMap : Map~String, Command~
- commandHistory : Deque~Command~
+ registerCommand(key : String, command : Command)
+ executeCommand(key : String)
+ undo()
}
class CrawlCommand {
- controller : CrawlerController
- site : String
- pageCount : int
+ execute()
+ getName() : String
+ getDescription() : String
}
class ExportDataCommand {
- controller : CrawlerController
- format : String
+ execute()
+ getName() : String
+ getDescription() : String
}
class GenerateChartCommand {
- controller : CrawlerController
+ execute()
+ getName() : String
+ getDescription() : String
}
class GenerateReportCommand {
- controller : CrawlerController
+ execute()
+ getName() : String
+ getDescription() : String
}
class MonitorCommand {
- broadcaster : DataBroadcaster
+ execute()
+ getName() : String
+ getDescription() : String
}
class ViewDataCommand {
- indexRepo : IndexDataRepository
- marketRepo : MarketDataRepository
+ execute()
+ getName() : String
+ getDescription() : String
}
class ExitCommand {
+ execute()
+ getName() : String
+ getDescription() : String
}
Command <|.. CrawlCommand
Command <|.. ExportDataCommand
Command <|.. GenerateChartCommand
Command <|.. GenerateReportCommand
Command <|.. MonitorCommand
Command <|.. ViewDataCommand
Command <|.. ExitCommand
CommandInvoker o-- Command : commands
}
' ========== 策略模式 ==========
package "strategy <<策略模式>>" #LightYellow {
interface CrawlStrategy {
+ crawlData(pageCount : int) : List~?~
+ saveData(dataList : List~?~) : int
+ getSiteName() : String
}
class CrawlStrategyFactory {
+ createStrategy(siteCode : String) : CrawlStrategy
}
class JinTouCrawlStrategy {
- repository : MarketDataRepository
+ crawlData(pageCount : int) : List~?~
+ saveData(dataList : List~?~) : int
+ getSiteName() : String
}
class EastMoneyCrawlStrategy {
- repository : IndexDataRepository
+ crawlData(pageCount : int) : List~?~
+ saveData(dataList : List~?~) : int
+ getSiteName() : String
}
class TongHuaShunCrawlStrategy {
- repository : NewsDataRepository
+ crawlData(pageCount : int) : List~?~
+ saveData(dataList : List~?~) : int
+ getSiteName() : String
}
CrawlStrategy <|.. JinTouCrawlStrategy
CrawlStrategy <|.. EastMoneyCrawlStrategy
CrawlStrategy <|.. TongHuaShunCrawlStrategy
CrawlStrategyFactory ..> CrawlStrategy : creates
}
' ========== 核心控制器 ==========
package "controller <<控制层>>" #LightGreen {
class CrawlerController {
+ crawl(siteCode : String, pageCount : int) : int
+ crawlAll(pageCount : int) : int
}
CrawlerController --> CrawlStrategyFactory : uses
}
' ========== 交互入口 ==========
package "cli <<表示层>>" #LightPink {
class InteractiveCLI {
- invoker : CommandInvoker
+ runInteractiveMode()
+ runCommandMode(args : String[])
+ main(args : String[])
}
InteractiveCLI --> CommandInvoker : uses
CommandInvoker --> CrawlerController : executes
}
' ========== 仓储层 ==========
package "repository <<仓储层>>" #LightGray {
class MarketDataRepository {
- sqlSessionFactory : SqlSessionFactory
+ save(data : MarketData) : int
+ batchSave(dataList : List~MarketData~) : int
+ findAll() : List~MarketData~
+ findByVariety(variety : String) : List~MarketData~
+ count() : int
}
class IndexDataRepository {
- sqlSessionFactory : SqlSessionFactory
+ save(data : IndexData) : int
+ batchSave(dataList : List~IndexData~) : int
+ findAll() : List~IndexData~
+ findByIndexName(indexName : String) : List~IndexData~
+ count() : int
}
class NewsDataRepository {
- sqlSessionFactory : SqlSessionFactory
+ save(data : NewsData) : int
+ batchSave(dataList : List~NewsData~) : int
+ findAll() : List~NewsData~
+ findByCommodity(commodity : String) : List~NewsData~
+ count() : int
}
}
' ========== 数据模型 ==========
package "model <<模型层>>" #White {
class MarketData {
- id : Long
- variety : String
- tradeDate : Date
- openPrice : BigDecimal
- closePrice : BigDecimal
- highPrice : BigDecimal
- lowPrice : BigDecimal
- volume : BigDecimal
- changeRate : BigDecimal
- createTime : Date
- source : String
}
class IndexData {
- id : Long
- indexName : String
- date : Date
- indexValue : BigDecimal
- changeRate : BigDecimal
- stockName : String
- stockPrice : BigDecimal
- turnoverRate : BigDecimal
- createTime : Date
- source : String
}
class NewsData {
- id : Long
- title : String
- content : String
- publishTime : Date
- relatedCommodity : String
- sentiment : String
- createTime : Date
- source : String
}
class PriceSnapshot {
- commodityName : String
- currentPrice : double
- changePercent : double
- timestamp : long
}
}
' ========== 工具类 ==========
package "util <<工具类>>" #Lavender {
class ChartGenerator {
+ generatePriceTrendChart(dataList : List~IndexData~) : BufferedImage
+ generateVolatilityChart(dataList : List~IndexData~) : BufferedImage
+ generateCorrelationChart(dataList : List~IndexData~) : BufferedImage
+ generateSentimentChart(dataList : List~NewsData~) : BufferedImage
}
class PdfReportGenerator {
- chineseFont : PDType0Font
+ generateReport(dataList : List~IndexData~, chartImages : Map~String, BufferedImage~, outputPath : String) : String
}
class ExcelExporter {
+ export(data : List~MarketData~, outputPath : String)
+ getFormat() : String
+ getFileExtension() : String
}
interface DataExporter {
+ export(data : List~MarketData~, outputPath : String)
+ getFormat() : String
+ getFileExtension() : String
}
class DataExporterFactory {
+ createExporter(format : String) : DataExporter
}
DataExporter <|.. ExcelExporter
DataExporter <|.. CsvExporter
DataExporter <|.. JsonExporter
}
package "monitor <<监控层>>" #LightCoral {
class DataBroadcaster {
- serverSocket : ServerSocket
- connections : Map~WebSocket, Player~
- scheduler : ScheduledExecutorService
+ start(port : int)
+ stop()
+ broadcast(message : String)
}
}
' ========== 异常 ==========
package "exception <<异常>>" #MistyRose {
class BaseCrawlException {
- errorCode : String
- errorMessage : String
- cause : Throwable
}
class NetworkException {
}
class ParseException {
}
class DbException {
}
class ParamException {
}
BaseCrawlException <|-- NetworkException
BaseCrawlException <|-- ParseException
BaseCrawlException <|-- DbException
BaseCrawlException <|-- ParamException
}
@enduml