99 lines
2.8 KiB
Plaintext
99 lines
2.8 KiB
Plaintext
' ============================================================
|
||
' WALKGUIDE — DESIGN PATTERNS (GoF)
|
||
' Flutter × Spring Boot × In-Device AI
|
||
' Pattern 5 of 7: OBSERVER (Behavioral)
|
||
' ============================================================
|
||
|
||
@startuml WalkGuide_05_Observer
|
||
|
||
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 5 — OBSERVER (Behavioral)
|
||
' ============================================================
|
||
|
||
package "⑤ Observer Pattern [Behavioral]" #F3E5F5 {
|
||
|
||
abstract class "Cubit<State>\n<<Subject>>" as BlocSubject {
|
||
# stateController : StreamController<State>
|
||
+ emit(State state)
|
||
+ stream : Stream<State>
|
||
}
|
||
|
||
class "WalkGuideCubit\n<<ConcreteSubject>>" as WalkGuideCubitObs {
|
||
+ start()
|
||
+ stop()
|
||
+ logObstacle()
|
||
- _yoloDetector : YoloDetector
|
||
- _ttsService : TtsService
|
||
- _hapticService : HapticService
|
||
}
|
||
|
||
class "BlocBuilder<WalkGuideCubit, WalkGuideState>\n<<Observer / Widget>>" as BlocBuilderWidget {
|
||
+ builder(ctx, state) : Widget
|
||
' Rebuilds UI on every state emission
|
||
}
|
||
|
||
class "BlocListener<WalkGuideCubit, WalkGuideState>\n<<Observer / SideEffect>>" as BlocListenerWidget {
|
||
+ listener(ctx, state) : void
|
||
' Side effects: TTS, haptic, navigation
|
||
}
|
||
|
||
class "WebSocketService\n<<Subject>>" as WebSocketObs {
|
||
- _stompClient : StompClient
|
||
+ subscribe(destination) : Stream<dynamic>
|
||
+ onLocationUpdate : StreamController
|
||
+ onSosAlert : StreamController
|
||
+ onNotification : StreamController
|
||
}
|
||
|
||
class "GuardianMapScreen\n<<Observer>>" as GuardianMapObs {
|
||
+ onLocationUpdate(LocationData)
|
||
' Updates flutter_map markers in real-time
|
||
}
|
||
|
||
BlocSubject <|-- WalkGuideCubitObs : extends
|
||
WalkGuideCubitObs --> BlocBuilderWidget : emits state\n(rebuilds UI)
|
||
WalkGuideCubitObs --> BlocListenerWidget : emits state\n(side effects)
|
||
WebSocketObs --> GuardianMapObs : notifies\nlive location
|
||
}
|
||
|
||
note left of WebSocketObs
|
||
Guardian subscribe topic:
|
||
/topic/location/{userId} — live map
|
||
/queue/sos/{guardianId} — SOS alert
|
||
/queue/notif/{userId} — notifications
|
||
STOMP over SockJS (stomp_dart_client)
|
||
end note
|
||
|
||
@enduml
|