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
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
|
|
|