102 lines
3.1 KiB
Plaintext
102 lines
3.1 KiB
Plaintext
' ============================================================
|
||
' WALKGUIDE — DESIGN PATTERNS (GoF)
|
||
' Flutter × Spring Boot × In-Device AI
|
||
' Pattern 4 of 7: REPOSITORY / PROXY (Structural)
|
||
' ============================================================
|
||
|
||
@startuml WalkGuide_04_Repository_Proxy
|
||
|
||
skinparam monochrome false
|
||
skinparam shadowing false
|
||
skinparam defaultFontName Arial
|
||
skinparam defaultFontSize 12
|
||
skinparam roundCorner 10
|
||
skinparam ArrowColor #555555
|
||
skinparam ArrowThickness 1.2
|
||
|
||
skinparam class {
|
||
BackgroundColor #FAFAFA
|
||
BorderColor #AAAAAA
|
||
HeaderBackgroundColor #E8E8E8
|
||
FontColor #222222
|
||
StereotypeFontColor #666666
|
||
AttributeFontColor #333333
|
||
}
|
||
|
||
skinparam package {
|
||
BackgroundColor #F5F5F5
|
||
BorderColor #888888
|
||
FontColor #333333
|
||
FontStyle bold
|
||
}
|
||
|
||
skinparam note {
|
||
BackgroundColor #FFFDE7
|
||
BorderColor #F9A825
|
||
FontColor #444444
|
||
FontSize 11
|
||
}
|
||
|
||
' ============================================================
|
||
' PATTERN 4 — REPOSITORY / PROXY (Structural)
|
||
' ============================================================
|
||
|
||
package "④ Repository Pattern [Structural — Proxy]" #FFF3E0 {
|
||
|
||
interface "WalkGuideRepository\n<<interface>>" as WalkGuideRepo {
|
||
+ startSession() : Either<Failure, void>
|
||
+ stopSession() : Either<Failure, void>
|
||
+ logObstacle(ObstacleLogRequest) : Either<Failure, void>
|
||
+ getObstacleLogs() : Either<Failure, List<ObstacleLog>>
|
||
}
|
||
|
||
interface "ActivityLogRepository\n<<interface>>" as ActivityRepo {
|
||
+ getLogs(page) : Either<Failure, List<ActivityLog>>
|
||
+ savePending(ActivityLog) : Either<Failure, void>
|
||
+ syncPending() : Either<Failure, void>
|
||
}
|
||
|
||
class "WalkGuideRepositoryImpl\n<<Proxy>>" as WalkGuideRepoImpl {
|
||
- _apiClient : ApiClient
|
||
- _offlineQueue : OfflineQueueService
|
||
- _connectivity : ConnectivityPlus
|
||
+ startSession() : Either<Failure, void>
|
||
+ logObstacle(req) : Either<Failure, void>
|
||
- _isOnline() : bool
|
||
}
|
||
|
||
class "ActivityLogRepositoryImpl\n<<Proxy>>" as ActivityRepoImpl {
|
||
- _remoteDataSource : ActivityRemoteDataSource
|
||
- _localDataSource : ActivityLocalDataSource
|
||
+ getLogs(page) : Either<Failure, List>
|
||
+ syncPending() : Either<Failure, void>
|
||
}
|
||
|
||
class "ApiClient\n<<Remote>>" as RemoteDSWalk {
|
||
+ startSession() : void
|
||
+ logObstacle(req) : void
|
||
' POST /api/v1/user/obstacle
|
||
}
|
||
|
||
class "OfflineQueueService + LocalDatabase\n<<SQLite Cache>>" as LocalDSWalk {
|
||
+ cacheObstacle(ObstacleLog) : void
|
||
+ getPendingLogs() : List<ObstacleLog>
|
||
' SQLite-backed offline first
|
||
}
|
||
|
||
WalkGuideRepo <|.. WalkGuideRepoImpl : implements
|
||
ActivityRepo <|.. ActivityRepoImpl : implements
|
||
WalkGuideRepoImpl --> RemoteDSWalk : online path
|
||
WalkGuideRepoImpl --> LocalDSWalk : offline path
|
||
}
|
||
|
||
note bottom of WalkGuideRepoImpl
|
||
Proxy memutuskan sumber data:
|
||
if (isOnline) → fetch remote API
|
||
else → baca/tulis SQLite (Drift)
|
||
Domain layer tidak tahu perbedaannya.
|
||
dartz Either<Failure, Data> untuk typed error.
|
||
end note
|
||
|
||
@enduml
|