@startuml
!theme plain
skinparam classAttributeIconSize 0
skinparam defaultFontSize 12
skinparam defaultFontName Microsoft YaHei
skinparam packageStyle rect
skinparam backgroundColor #FFFFFF
skinparam dpi 300
' 类样式
skinparam class {
BackgroundColor White
ArrowColor DarkGray
BorderColor Black
Padding 5
FontSize 11
}
' 接口样式
skinparam interface {
BackgroundColor LightBlue
BorderColor SteelBlue
Padding 5
FontSize 11
StereotypeFontSize 10
}
' 包样式
skinparam package {
BackgroundColor WhiteSmoke
BorderColor Gray
Padding 10
FontSize 13
FontStyle Bold
}
' 箭头样式
skinparam ArrowColor DarkSlateGray
skinparam ArrowFontSize 10
skinparam ArrowThickness 1.5
skinparam Linetype ortho
title 爬虫项目类图
' 强制垂直布局,避免过宽
top to bottom direction
left to right direction
package "交互层" #E3F2FD {
class InteractiveCLI {
- running: boolean
- commands: Map
- persistenceManager: DataPersistenceManager
+ run(): void
- showHelp(): void
}
class DataView {
+ displayRouteInfo(RouteInfo): void
+ displayWeatherInfo(WeatherInfo): void
+ displayAttractionInfo(List): void
+ displayHeader(String): void
+ displayError(String): void
}
}
package "命令层" #FFF3E0 {
interface Command {
+ execute(String[]): void
}
class RouteCommand {
- routeService: RouteService
- view: DataView
- persistenceManager: DataPersistenceManager
- lastRoute: RouteInfo
}
class WeatherCommand {
- weatherService: WeatherServiceManager
- view: DataView
- persistenceManager: DataPersistenceManager
- lastWeather: WeatherInfo
}
class AttractionCommand {
- attractionService: AttractionService
- view: DataView
- persistenceManager: DataPersistenceManager
- lastAttractions: List
}
class ExportCommand {
- exporter: JsonExporter
- routeSupplier: Supplier
- weatherSupplier: Supplier
- attractionSupplier: Supplier
}
class ImportCommand {
- importer: JsonImporter
- view: DataView
}
}
package "服务层" #E8F5E9 {
class RouteService {
- apiKey: String
- platform: MapPlatform
+ getRouteInfo(origin, dest, strategy): RouteInfo
}
class WeatherServiceManager {
- services: List
+ getWeatherInfo(city): WeatherInfo
}
interface WeatherService {
+ getWeather(city): WeatherInfo
}
class FreeWeatherService {
- baseUrl: String
+ getWeather(city): WeatherInfo
}
class AttractionService {
- crawler: BaiduBaikeAttractionCrawler
+ searchAttractions(city): List
}
}
package "爬虫层" #FCE4EC {
class BaiduBaikeAttractionCrawler {
- baseUrl: String
- timeout: int
+ searchAttractions(city): List
- parseHtml(doc, city): List
}
}
package "策略层" #F3E5F5 {
interface TransportStrategy {
+ getType(): String
+ getApiEndpoint(): String
}
class DrivingStrategy {
+ getType(): String
+ getApiEndpoint(): String
}
class BusStrategy {
+ getType(): String
+ getApiEndpoint(): String
}
}
package "平台层" #FFF8E1 {
interface MapPlatform {
+ getName(): String
+ getRouteUrl(): String
+ geocode(address): String
}
class AmapPlatform {
- apiKey: String
+ getName(): String
+ getRouteUrl(): String
}
class BaiduPlatform {
- apiKey: String
+ getName(): String
+ getRouteUrl(): String
}
class TencentPlatform {
- apiKey: String
+ getName(): String
+ getRouteUrl(): String
}
}
package "数据模型" #FFEBEE {
class RouteInfo {
- mapType: String
- transportType: String
- distance: double
- time: double
- origin: String
- destination: String
}
class WeatherInfo {
- city: String
- temperature: double
- feelsLike: double
- weather: String
- windDirection: String
- windSpeed: double
- humidity: int
- visibility: double
- updateTime: String
}
class AttractionInfo {
- name: String
- city: String
- level: String
- score: double
- ticketPrice: double
- openTime: String
- address: String
- description: String
}
}
package "工具层" #ECEFF1 {
class DataPersistenceManager {
- objectMapper: ObjectMapper
- routeData: List
- weatherData: List
- attractionData: List
+ addRouteData(route): void
+ addWeatherData(weather): void
+ addAttractionData(attraction): void
+ saveAllData(): void
+ loadSavedData(): void
+ getStats(): String
}
class JsonExporter {
- mapper: ObjectMapper
+ exportRoute(route, from, to): void
+ exportWeather(weather): void
+ exportAttractions(attractions, city): void
- generateFileName(type, name): String
}
class JsonImporter {
- mapper: ObjectMapper
+ importRoute(filePath): RouteInfo
+ importWeather(filePath): WeatherInfo
+ importAttractions(filePath): List
}
class CityList {
- CITIES: Map
+ selectCity(reader, prompt): String
+ getCoordinates(city): String
}
}
' ==================== 关系定义 ====================
' 使用隐藏连线强制垂直布局顺序
InteractiveCLI -[hidden]down-> RouteCommand : ""
RouteCommand -[hidden]down-> RouteService : ""
RouteService -[hidden]down-> TransportStrategy : ""
TransportStrategy -[hidden]down-> MapPlatform : ""
MapPlatform -[hidden]down-> RouteInfo : ""
RouteInfo -[hidden]down-> DataPersistenceManager : ""
WeatherServiceManager -[hidden]down-> WeatherService : ""
AttractionService -[hidden]down-> BaiduBaikeAttractionCrawler : ""
' 交互层关系
InteractiveCLI --> Command : 使用
InteractiveCLI --> DataView : 显示
InteractiveCLI --> DataPersistenceManager : 持久化
' 命令实现关系
RouteCommand ..|> Command : 实现
WeatherCommand ..|> Command : 实现
AttractionCommand ..|> Command : 实现
ExportCommand ..|> Command : 实现
ImportCommand ..|> Command : 实现
' 命令调用服务
RouteCommand --> RouteService : 调用
WeatherCommand --> WeatherServiceManager : 调用
AttractionCommand --> AttractionService : 调用
' 服务层关系
RouteService --> TransportStrategy : 使用策略
RouteService --> MapPlatform : 使用平台
WeatherServiceManager ..> WeatherService : 管理
FreeWeatherService ..|> WeatherService : 实现
AttractionService --> BaiduBaikeAttractionCrawler : 使用爬虫
' 策略实现关系
DrivingStrategy ..|> TransportStrategy : 实现
BusStrategy ..|> TransportStrategy : 实现
' 平台实现关系
AmapPlatform ..|> MapPlatform : 实现
BaiduPlatform ..|> MapPlatform : 实现
TencentPlatform ..|> MapPlatform : 实现
' 数据返回关系
RouteService ..> RouteInfo : 返回
WeatherServiceManager ..> WeatherInfo : 返回
AttractionService ..> AttractionInfo : 返回
' 视图显示关系
DataView --> RouteInfo : 显示
DataView --> WeatherInfo : 显示
DataView --> AttractionInfo : 显示
' 持久化关系
DataPersistenceManager --> RouteInfo : 保存
DataPersistenceManager --> WeatherInfo : 保存
DataPersistenceManager --> AttractionInfo : 保存
@enduml