generated from Grigo/AndroidTemplate
938 lines
28 KiB
Markdown
938 lines
28 KiB
Markdown
# Диаграмма классов AIS Map Application (Финальная архитектура)
|
|
|
|
```mermaid
|
|
classDiagram
|
|
%% Основные Activity и UI компоненты
|
|
class MainActivity {
|
|
-AppCoordinator appCoordinator
|
|
-MenuBinder menuBinder
|
|
-BottomSheetsBinder bottomSheetsBinder
|
|
-PermissionsBinder permissionsBinder
|
|
-MapController mapController
|
|
-CompassController compassController
|
|
-UIRenderingCoordinator uiCoordinator
|
|
-MapView mapView
|
|
-SettingsManager settingsManager
|
|
-CompassView compassView
|
|
-CoordinatesDockWidget coordinatesWidget
|
|
-BottomSheetsManager bottomSheetsManager
|
|
+onCreate()
|
|
+onResume()
|
|
+onPause()
|
|
+onDestroy()
|
|
+onCreateOptionsMenu()
|
|
+onOptionsItemSelected()
|
|
}
|
|
|
|
class AisTargetsActivity {
|
|
-AisTargetsAdapter adapter
|
|
-List~AISVessel~ aisVessels
|
|
+onCreate()
|
|
+updateAISList()
|
|
}
|
|
|
|
class SettingsActivity {
|
|
-SettingsManager settingsManager
|
|
+onCreate()
|
|
+saveSettings()
|
|
}
|
|
|
|
%% Главный координатор приложения
|
|
class AppCoordinator {
|
|
-Context context
|
|
-NMEAController nmeaController
|
|
-NetworkController networkController
|
|
-DataController dataController
|
|
-NotificationController notificationController
|
|
-CompassController compassController
|
|
-MapController mapController
|
|
-Vessel ownVessel
|
|
-List~AISVessel~ aisVessels
|
|
-Map~String, VesselPathController~ aisPathControllers
|
|
-SettingsManager settingsManager
|
|
-VesselPathController pathController
|
|
-UIDataChangeNotifier uiDataNotifier
|
|
-Handler uiHandler
|
|
-AppCoordinatorListener listener
|
|
+initializeControllers()
|
|
+startServices()
|
|
+stopServices()
|
|
+onVesselUpdated()
|
|
+onAISVesselUpdated()
|
|
+onDOPUpdated()
|
|
+onDataReceived()
|
|
+onNotificationShown()
|
|
+onCompassChanged()
|
|
+isAndroidNMEAEnabled()
|
|
+isUDPEnabled()
|
|
}
|
|
|
|
%% Фабрика контроллеров
|
|
class ControllersFactory {
|
|
<<interface>>
|
|
+createAppCoordinator() AppCoordinator
|
|
}
|
|
|
|
class DefaultControllersFactory {
|
|
+createAppCoordinator() AppCoordinator
|
|
}
|
|
|
|
%% Специализированные контроллеры
|
|
class NMEAController {
|
|
-Context context
|
|
-NMEAParser nmeaParser
|
|
-AndroidNMEAListener androidNmeaListener
|
|
-GPSLocationListener gpsLocationListener
|
|
-ExecutorService executor
|
|
-NMEAControllerListener listener
|
|
+startAndroidNMEAListener()
|
|
+stopAndroidNMEAListener()
|
|
+startGPSLocationListener()
|
|
+stopGPSLocationListener()
|
|
+parseNMEAData()
|
|
+onVesselUpdated()
|
|
+onAISVesselUpdated()
|
|
+onDOPUpdated()
|
|
}
|
|
|
|
class NetworkController {
|
|
-Context context
|
|
-UDPListener udpListener
|
|
-ExecutorService executor
|
|
-int udpPort
|
|
-boolean isUDPEnabled
|
|
-boolean isUDPNMEAEnabled
|
|
-NetworkControllerListener listener
|
|
+setUDPEnabled()
|
|
+startUDPListener()
|
|
+stopUDPListener()
|
|
+onDataReceived()
|
|
+onUDPError()
|
|
}
|
|
|
|
class DataController {
|
|
-Context context
|
|
-Repository repository
|
|
-SettingsManager settingsManager
|
|
-ExecutorService executor
|
|
-Handler dbCleanupHandler
|
|
-Runnable dbCleanupRunnable
|
|
-DataControllerListener listener
|
|
+restoreDataAsync()
|
|
+saveVesselData()
|
|
+saveAISData()
|
|
+performDatabaseCleanup()
|
|
+onDataRestored()
|
|
+onDataSaved()
|
|
+onDataCleaned()
|
|
}
|
|
|
|
class NotificationController {
|
|
-Context context
|
|
-NotificationService notificationService
|
|
-NotificationControllerListener listener
|
|
+notifyNewAISTarget()
|
|
+notifySafetyMessage()
|
|
+notifyGPSStatus()
|
|
+onNotificationShown()
|
|
+onNotificationError()
|
|
}
|
|
|
|
class CompassController {
|
|
-Context context
|
|
-CompassSensor compassSensor
|
|
-Handler uiHandler
|
|
-CompassControllerListener listener
|
|
+startCompass()
|
|
+stopCompass()
|
|
+isCompassAvailable()
|
|
+isCompassActive()
|
|
+getCompassStatus()
|
|
+onCompassChanged()
|
|
+onCompassError()
|
|
}
|
|
|
|
class MapController {
|
|
-Context context
|
|
-MapInterface currentMapInterface
|
|
-MapView mapView
|
|
-org.maplibre.android.maps.MapView mapLibreView
|
|
-List~MapInterfaceChangeListener~ listeners
|
|
+addMapInterfaceChangeListener()
|
|
+removeMapInterfaceChangeListener()
|
|
+switchToYandexMaps()
|
|
+switchToMapLibre()
|
|
+getCurrentMapInterface()
|
|
}
|
|
|
|
%% UI Binders (новая архитектура)
|
|
class MenuBinder {
|
|
-AppCoordinator appCoordinator
|
|
-SettingsManager settingsManager
|
|
-MenuActions actions
|
|
+onCreateOptionsMenu()
|
|
+onPrepareOptionsMenu()
|
|
+onOptionsItemSelected()
|
|
}
|
|
|
|
class BottomSheetsBinder {
|
|
-Context context
|
|
-BottomSheetDialog ownVesselBottomSheet
|
|
-BottomSheetDialog aisVesselBottomSheet
|
|
-View ownBottomSheetView
|
|
-View aisBottomSheetView
|
|
-AISVessel currentAISVessel
|
|
-Handler updateHandler
|
|
-Runnable updateRunnable
|
|
+init()
|
|
+initAIS()
|
|
+showOwnVesselSheet()
|
|
+showAISVesselSheet()
|
|
+startAutoUpdate()
|
|
+stopAutoUpdate()
|
|
}
|
|
|
|
class BottomSheetsManager {
|
|
-Context context
|
|
-AppCoordinator appCoordinator
|
|
-BottomSheetDialog ownVesselBottomSheet
|
|
-BottomSheetDialog aisVesselBottomSheet
|
|
-View bottomSheetView
|
|
-View aisBottomSheetView
|
|
-AISVessel currentAISVessel
|
|
-Handler timeUpdateHandler
|
|
-Handler bottomSheetUpdateHandler
|
|
+init()
|
|
+showOwnVesselSheet()
|
|
+showAISVesselSheet()
|
|
+updateOwnVesselUI()
|
|
+updateAISBottomSheetUI()
|
|
+stopAutoUpdate()
|
|
}
|
|
|
|
class PermissionsBinder {
|
|
-Activity activity
|
|
+ensurePermission()
|
|
+handleOnRequestPermissionsResult()
|
|
}
|
|
|
|
%% Базовые компоненты
|
|
class NMEAParser {
|
|
-Vessel ownVessel
|
|
-List~AISVessel~ aisVessels
|
|
-NMEAParserListener listener
|
|
-GPSLocationListener gpsLocationListener
|
|
-Map~String, Map~Integer, String~~ aisFragments
|
|
-boolean hybridMode
|
|
+parseNMEA()
|
|
+setHybridMode()
|
|
+setGPSLocationListener()
|
|
}
|
|
|
|
class UDPListener {
|
|
-int port
|
|
-DatagramSocket socket
|
|
-ExecutorService executor
|
|
-AtomicBoolean isRunning
|
|
-UDPListenerCallback callback
|
|
+start()
|
|
+stop()
|
|
+setCallback()
|
|
}
|
|
|
|
class AndroidNMEAListener {
|
|
-LocationManager locationManager
|
|
-NMEAMessageCallback callback
|
|
-boolean isListening
|
|
+startListening()
|
|
+stopListening()
|
|
+setCallback()
|
|
}
|
|
|
|
class GPSLocationListener {
|
|
-Context context
|
|
-LocationManager locationManager
|
|
-LocationCallback callback
|
|
-boolean isListening
|
|
-int satelliteCount
|
|
-int activeSatellites
|
|
-double pdop
|
|
-double hdop
|
|
-double vdop
|
|
+startListening()
|
|
+stopListening()
|
|
+setCallback()
|
|
}
|
|
|
|
class VesselPathController {
|
|
-Context context
|
|
-SettingsManager settingsManager
|
|
-SharedPreferences prefs
|
|
-String vesselId
|
|
-Handler uiHandler
|
|
-List~VesselPathPoint~ pathPoints
|
|
-VesselPathPoint lastPoint
|
|
+addPathPoint()
|
|
+getPathPoints()
|
|
+clearPath()
|
|
+savePath()
|
|
+loadPath()
|
|
}
|
|
|
|
%% Интерфейсы карт
|
|
class MapInterface {
|
|
<<interface>>
|
|
+initialize()
|
|
+cleanup()
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselPosition()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselPosition()
|
|
+removeAISVesselMarker()
|
|
+clearAISVesselMarkers()
|
|
+centerOnPosition()
|
|
+setZoom()
|
|
+getZoom()
|
|
+setBearing()
|
|
+getBearing()
|
|
+addLayer()
|
|
+removeLayer()
|
|
+setMarkerClickListener()
|
|
+clearVesselPath()
|
|
+showCursor()
|
|
+hideCursor()
|
|
+updateCursorCoordinates()
|
|
+updateCursorFromMapCenter()
|
|
+setAisVesselInfo()
|
|
+clearAisVesselInfo()
|
|
}
|
|
|
|
class MapInterfaceChangeListener {
|
|
<<interface>>
|
|
+onMapInterfaceChanged()
|
|
}
|
|
|
|
class MarkerClickListener {
|
|
<<interface>>
|
|
+onOwnVesselClick()
|
|
+onAISVesselClick()
|
|
}
|
|
|
|
%% Реализации карт
|
|
class YandexMapImpl {
|
|
-Context context
|
|
-MapView mapView
|
|
-MapObjectCollection mapObjects
|
|
-MarkerClickListener markerClickListener
|
|
-YandexMarkerManager markerManager
|
|
-CursorOverlay cursorOverlay
|
|
-Vessel ownVessel
|
|
+initialize()
|
|
+cleanup()
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselPosition()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselPosition()
|
|
+removeAISVesselMarker()
|
|
+clearAISVesselMarkers()
|
|
+centerOnPosition()
|
|
+setZoom()
|
|
+getZoom()
|
|
+setBearing()
|
|
+getBearing()
|
|
}
|
|
|
|
class MapLibreMapImpl {
|
|
-Context context
|
|
-MapView mapView
|
|
-MapLibreMap mapLibreMap
|
|
-MarkerClickListener markerClickListener
|
|
-CursorOverlay cursorOverlay
|
|
-Vessel ownVessel
|
|
-Map~String, AISVessel~ aisVessels
|
|
+initialize()
|
|
+cleanup()
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselPosition()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselPosition()
|
|
+removeAISVesselMarker()
|
|
+clearAISVesselMarkers()
|
|
+centerOnPosition()
|
|
+setZoom()
|
|
+getZoom()
|
|
+setBearing()
|
|
+getBearing()
|
|
}
|
|
|
|
class MapForgeImpl {
|
|
-Context context
|
|
-MapView mapView
|
|
-MarkerClickListener markerClickListener
|
|
-CursorOverlay cursorOverlay
|
|
-Vessel ownVessel
|
|
+initialize()
|
|
+cleanup()
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselPosition()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselPosition()
|
|
+removeAISVesselMarker()
|
|
+clearAISVesselMarkers()
|
|
+centerOnPosition()
|
|
+setZoom()
|
|
+getZoom()
|
|
+setBearing()
|
|
+getBearing()
|
|
}
|
|
|
|
%% Менеджеры маркеров
|
|
class YandexMarkerManager {
|
|
-MapObjectCollection mapObjects
|
|
-Map~String, YandexMarkerWrapper~ ownVesselMarkers
|
|
-Map~String, YandexMarkerWrapper~ aisVesselMarkers
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselMarker()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselMarker()
|
|
+removeAISVesselMarker()
|
|
+clearAllMarkers()
|
|
}
|
|
|
|
class MarkerManager {
|
|
-MapLibreMap mapLibreMap
|
|
-Map~String, MarkerWrapper~ ownVesselMarkers
|
|
-Map~String, MarkerWrapper~ aisVesselMarkers
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselMarker()
|
|
+addAISVesselMarker()
|
|
+updateAISVesselMarker()
|
|
+removeAISVesselMarker()
|
|
+clearAllMarkers()
|
|
}
|
|
|
|
%% Модели данных
|
|
class Vessel {
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-double heading
|
|
-double magneticCompass
|
|
-int signalStrength
|
|
-LocalDateTime lastUpdate
|
|
-String vesselName
|
|
-String mmsi
|
|
-String callSign
|
|
-double altitude
|
|
-int satellites
|
|
-int activeSatellites
|
|
-double pdop
|
|
-double hdop
|
|
-double vdop
|
|
-float accuracy
|
|
-long fixTime
|
|
-String fixQuality
|
|
+updatePosition()
|
|
+updateGPSQuality()
|
|
+getGPSQualityPercentage()
|
|
+getGPSQualityDescription()
|
|
}
|
|
|
|
class AISVessel {
|
|
-String mmsi
|
|
-String vesselName
|
|
-String callSign
|
|
-int imo
|
|
-String vesselType
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-double heading
|
|
-double rateOfTurn
|
|
-double length
|
|
-double width
|
|
-double draft
|
|
-String destination
|
|
-LocalDateTime eta
|
|
-LocalDateTime lastUpdate
|
|
-int signalStrength
|
|
-boolean isActive
|
|
-String navigationalStatus
|
|
-String lastSafetyMessage
|
|
-boolean positionAccuracy
|
|
-String vesselClass
|
|
-String vendorId
|
|
-boolean selected
|
|
+updatePosition()
|
|
+isDataStale()
|
|
+shouldBeRemoved()
|
|
+getMinutesSinceLastUpdate()
|
|
}
|
|
|
|
class VesselPathPoint {
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-long timestamp
|
|
+VesselPathPoint()
|
|
+toJSON()
|
|
+fromJSON()
|
|
}
|
|
|
|
%% База данных и репозиторий
|
|
class AppDatabase {
|
|
<<abstract>>
|
|
+aisVesselDao() AISVesselDao
|
|
+vesselDao() VesselDao
|
|
+getInstance() AppDatabase
|
|
}
|
|
|
|
class Repository {
|
|
-AISVesselDao aisVesselDao
|
|
-VesselDao vesselDao
|
|
-ExecutorService ioExecutor
|
|
+upsertAIS()
|
|
+deleteStaleAIS()
|
|
+getAllAISSync()
|
|
+observeAllAIS()
|
|
+getAISByMmsiSync()
|
|
+upsertOwnVessel()
|
|
+getLatestOwnVesselSync()
|
|
+getLatestOwnVesselAsync()
|
|
}
|
|
|
|
class AISVesselDao {
|
|
<<interface>>
|
|
+upsert()
|
|
+deleteStale()
|
|
+getAll()
|
|
+observeAll()
|
|
+getByMmsi()
|
|
}
|
|
|
|
class VesselDao {
|
|
<<interface>>
|
|
+upsert()
|
|
+getLatest()
|
|
}
|
|
|
|
class AISVesselEntity {
|
|
-String mmsi
|
|
-String vesselName
|
|
-String callSign
|
|
-int imo
|
|
-String vesselType
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-double heading
|
|
-double rateOfTurn
|
|
-double length
|
|
-double width
|
|
-double draft
|
|
-String destination
|
|
-long etaEpochMs
|
|
-long lastUpdateEpochMs
|
|
-int signalStrength
|
|
-boolean isActive
|
|
-String navigationalStatus
|
|
-String lastSafetyMessage
|
|
-boolean positionAccuracy
|
|
-String vesselClass
|
|
-String vendorId
|
|
}
|
|
|
|
class VesselEntity {
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-double heading
|
|
-double magneticCompass
|
|
-int signalStrength
|
|
-long lastUpdateEpochMs
|
|
-String vesselName
|
|
-String mmsi
|
|
-String callSign
|
|
-double altitude
|
|
-int satellites
|
|
-int activeSatellites
|
|
-double pdop
|
|
-double hdop
|
|
-double vdop
|
|
-float accuracy
|
|
-long fixTime
|
|
-String fixQuality
|
|
}
|
|
|
|
%% UI компоненты
|
|
class UIRenderingCoordinator {
|
|
-MapInterface mapInterface
|
|
-Handler uiHandler
|
|
-Vessel pendingVesselUpdate
|
|
-Map~String, AISVessel~ pendingAISUpdates
|
|
-Set~String~ pendingAISRemovals
|
|
-Runnable vesselUpdateRunnable
|
|
-Runnable aisUpdateRunnable
|
|
-Runnable pathUpdateRunnable
|
|
-boolean vesselUpdatePending
|
|
-boolean aisUpdatePending
|
|
-boolean pathUpdatePending
|
|
+requestVesselUpdate()
|
|
+requestAISUpdate()
|
|
+requestAISRemoval()
|
|
+flushPendingOperations()
|
|
+cleanup()
|
|
}
|
|
|
|
class UIDataChangeNotifier {
|
|
<<interface>>
|
|
+onVesselPositionChanged()
|
|
+onGPSQualityChanged()
|
|
+onAISVesselChanged()
|
|
+onAISVesselRemoved()
|
|
+onVesselPathChanged()
|
|
+onRequestCenterMap()
|
|
+onCompassUpdate()
|
|
}
|
|
|
|
class CompassView {
|
|
-float azimuth
|
|
-Paint compassPaint
|
|
-Paint needlePaint
|
|
-Paint textPaint
|
|
-List~AISVessel~ nearbyVessels
|
|
+setAzimuth()
|
|
+setNearbyVessels()
|
|
+onDraw()
|
|
}
|
|
|
|
class CompassSensor {
|
|
-SensorManager sensorManager
|
|
-Sensor magnetometer
|
|
-Sensor accelerometer
|
|
-CompassListener callback
|
|
-float[] lastAccelerometer
|
|
-float[] lastMagnetometer
|
|
-boolean lastAccelerometerSet
|
|
-boolean lastMagnetometerSet
|
|
-float[] rotationMatrix
|
|
-float[] orientation
|
|
+startListening()
|
|
+stopListening()
|
|
+setCallback()
|
|
}
|
|
|
|
class CoordinatesDockWidget {
|
|
-TextView latitudeText
|
|
-TextView longitudeText
|
|
-TextView accuracyText
|
|
-TextView satellitesText
|
|
-TextView qualityText
|
|
+updateCoordinates()
|
|
+updateGPSQuality()
|
|
}
|
|
|
|
class CursorOverlay {
|
|
-ViewGroup parentView
|
|
-TextView coordinatesText
|
|
-TextView vesselInfoText
|
|
-boolean isVisible
|
|
+show()
|
|
+hide()
|
|
+updateCoordinates()
|
|
+setVesselInfo()
|
|
+clearVesselInfo()
|
|
}
|
|
|
|
%% Сервисы
|
|
class NotificationService {
|
|
-Context context
|
|
-SettingsManager settingsManager
|
|
-Vibrator vibrator
|
|
-ToneGenerator toneGenerator
|
|
-boolean isInitialized
|
|
+showSafetyAlert()
|
|
+showNewVesselNotification()
|
|
+clearNotifications()
|
|
+setVibrationEnabled()
|
|
+setSoundEnabled()
|
|
}
|
|
|
|
class AISForegroundService {
|
|
-Context context
|
|
-AppCoordinator appCoordinator
|
|
-NotificationManager notificationManager
|
|
-boolean isRunning
|
|
+startForeground()
|
|
+stopForeground()
|
|
+onStartCommand()
|
|
+onDestroy()
|
|
}
|
|
|
|
%% Утилиты
|
|
class SettingsManager {
|
|
-Context context
|
|
-SharedPreferences prefs
|
|
+getUDPPort()
|
|
+setUDPPort()
|
|
+isUDPEnabled()
|
|
+setUDPEnabled()
|
|
+isAndroidNMEAEnabled()
|
|
+setAndroidNMEAEnabled()
|
|
+isUDPNMEAEnabled()
|
|
+setUDPNMEAEnabled()
|
|
+getDataMode()
|
|
+setDataMode()
|
|
+getDataStaleWarningMinutes()
|
|
+setDataStaleWarningMinutes()
|
|
+getDataStaleRemoveMinutes()
|
|
+setDataStaleRemoveMinutes()
|
|
+isPathTrackingEnabled()
|
|
+setPathTrackingEnabled()
|
|
+getPathColor()
|
|
+setPathColor()
|
|
+getPredictionColor()
|
|
+setPredictionColor()
|
|
+getPathWidth()
|
|
+setPathWidth()
|
|
+getPredictionWidth()
|
|
+setPredictionWidth()
|
|
+getPathMaxPoints()
|
|
+setPathMaxPoints()
|
|
+getPredictionHorizonSec()
|
|
+setPredictionHorizonSec()
|
|
+isVibrationEnabled()
|
|
+setVibrationEnabled()
|
|
+isSoundEnabled()
|
|
+setSoundEnabled()
|
|
+isKeepScreenOnEnabled()
|
|
+setKeepScreenOnEnabled()
|
|
+isCursorEnabled()
|
|
+setCursorEnabled()
|
|
}
|
|
|
|
class GeoUtils {
|
|
<<utility>>
|
|
+calculateDistance()
|
|
+calculateBearing()
|
|
+isValidCoordinate()
|
|
+formatCoordinate()
|
|
+convertToDecimalDegrees()
|
|
}
|
|
|
|
class LogSender {
|
|
<<utility>>
|
|
+sendLog()
|
|
+sendError()
|
|
+sendWarning()
|
|
+sendInfo()
|
|
}
|
|
|
|
class MIDToCountry {
|
|
<<utility>>
|
|
+getCountryByMID()
|
|
+getCountryName()
|
|
+isValidMID()
|
|
}
|
|
|
|
class NavigationUtils {
|
|
<<utility>>
|
|
+calculateCourse()
|
|
+calculateSpeed()
|
|
+calculateETA()
|
|
+isCollisionRisk()
|
|
}
|
|
|
|
%% Связи между классами (финальная архитектура)
|
|
MainActivity --> AppCoordinator : uses
|
|
MainActivity --> MenuBinder : uses
|
|
MainActivity --> BottomSheetsBinder : uses
|
|
MainActivity --> PermissionsBinder : uses
|
|
MainActivity --> MapController : uses
|
|
MainActivity --> CompassController : uses
|
|
MainActivity --> UIRenderingCoordinator : uses
|
|
MainActivity --> CompassView : uses
|
|
MainActivity --> CoordinatesDockWidget : uses
|
|
MainActivity --> BottomSheetsManager : uses
|
|
|
|
%% Фабрика контроллеров
|
|
ControllersFactory <|.. DefaultControllersFactory : implements
|
|
MainActivity --> ControllersFactory : uses
|
|
DefaultControllersFactory --> AppCoordinator : creates
|
|
|
|
%% AppCoordinator координирует все контроллеры
|
|
AppCoordinator --> NMEAController : coordinates
|
|
AppCoordinator --> NetworkController : coordinates
|
|
AppCoordinator --> DataController : coordinates
|
|
AppCoordinator --> NotificationController : coordinates
|
|
AppCoordinator --> CompassController : coordinates
|
|
AppCoordinator --> MapController : coordinates
|
|
AppCoordinator --> VesselPathController : uses
|
|
AppCoordinator --> SettingsManager : uses
|
|
AppCoordinator --> UIRenderingCoordinator : uses
|
|
|
|
%% Специализированные контроллеры
|
|
NMEAController --> NMEAParser : uses
|
|
NMEAController --> AndroidNMEAListener : uses
|
|
NMEAController --> GPSLocationListener : uses
|
|
|
|
NetworkController --> UDPListener : uses
|
|
|
|
DataController --> Repository : uses
|
|
DataController --> SettingsManager : uses
|
|
|
|
NotificationController --> NotificationService : uses
|
|
|
|
CompassController --> CompassSensor : uses
|
|
|
|
%% UI Binders
|
|
MenuBinder --> AppCoordinator : uses
|
|
MenuBinder --> SettingsManager : uses
|
|
BottomSheetsBinder --> Context : uses
|
|
BottomSheetsManager --> AppCoordinator : uses
|
|
PermissionsBinder --> Activity : uses
|
|
|
|
%% Карты
|
|
MapController --> MapInterface : manages
|
|
MapController --> YandexMapImpl : creates
|
|
MapController --> MapLibreMapImpl : creates
|
|
MapController --> MapForgeImpl : creates
|
|
MapController --> MapInterfaceChangeListener : notifies
|
|
|
|
YandexMapImpl ..|> MapInterface : implements
|
|
MapLibreMapImpl ..|> MapInterface : implements
|
|
MapForgeImpl ..|> MapInterface : implements
|
|
|
|
YandexMapImpl --> YandexMarkerManager : uses
|
|
MapLibreMapImpl --> MarkerManager : uses
|
|
|
|
%% База данных
|
|
Repository --> AppDatabase : uses
|
|
Repository --> AISVesselDao : uses
|
|
Repository --> VesselDao : uses
|
|
|
|
AppDatabase --> AISVesselEntity : contains
|
|
AppDatabase --> VesselEntity : contains
|
|
|
|
%% UI координация
|
|
UIRenderingCoordinator ..|> UIDataChangeNotifier : implements
|
|
UIRenderingCoordinator ..|> MapInterfaceChangeListener : implements
|
|
|
|
%% Данные
|
|
NMEAParser --> Vessel : creates/updates
|
|
NMEAParser --> AISVessel : creates/updates
|
|
NMEAParser --> GPSLocationListener : uses
|
|
|
|
VesselPathController --> VesselPathPoint : manages
|
|
VesselPathController --> SettingsManager : uses
|
|
|
|
%% Сервисы
|
|
NotificationService --> SettingsManager : uses
|
|
|
|
%% Компас
|
|
CompassSensor --> CompassView : updates
|
|
CompassView --> AISVessel : displays
|
|
|
|
%% Интерфейсы и их реализации (финальная архитектура)
|
|
AppCoordinator ..|> NMEAControllerListener : implements
|
|
AppCoordinator ..|> NetworkControllerListener : implements
|
|
AppCoordinator ..|> DataControllerListener : implements
|
|
AppCoordinator ..|> NotificationControllerListener : implements
|
|
AppCoordinator ..|> CompassControllerListener : implements
|
|
AppCoordinator ..|> MarkerClickListener : implements
|
|
AppCoordinator ..|> MapInterfaceChangeListener : implements
|
|
|
|
NMEAController ..|> NMEAParserListener : implements
|
|
NMEAController ..|> NMEAMessageCallback : implements
|
|
|
|
NetworkController ..|> UDPListenerCallback : implements
|
|
|
|
CompassController ..|> CompassListener : implements
|
|
|
|
NMEAParser ..|> NMEAParserListener : implements
|
|
UDPListener ..|> UDPListenerCallback : implements
|
|
AndroidNMEAListener ..|> NMEAMessageCallback : implements
|
|
GPSLocationListener ..|> LocationCallback : implements
|
|
CompassSensor ..|> CompassListener : implements
|
|
```
|
|
|
|
## Описание финальной архитектуры
|
|
|
|
### 🏗️ **Основные принципы архитектуры:**
|
|
|
|
#### **1. Разделение ответственности (Single Responsibility Principle)**
|
|
- Каждый контроллер отвечает за одну конкретную область функциональности
|
|
- UI компоненты разделены на специализированные Binder'ы
|
|
- Четкое разделение между слоями данных, бизнес-логики и представления
|
|
|
|
#### **2. Координаторный паттерн (Coordinator Pattern)**
|
|
- **AppCoordinator** - центральный координатор всех контроллеров
|
|
- Управляет жизненным циклом и взаимодействием между компонентами
|
|
- Единая точка входа для всех событий и состояний
|
|
|
|
#### **3. Фабричный паттерн (Factory Pattern)**
|
|
- **ControllersFactory** - интерфейс для создания контроллеров
|
|
- **DefaultControllersFactory** - базовая реализация фабрики
|
|
- Позволяет легко тестировать и заменять компоненты
|
|
|
|
### 📦 **Специализированные контроллеры:**
|
|
|
|
1. **NMEAController** - парсинг и обработка NMEA сообщений
|
|
2. **NetworkController** - UDP слушание и сетевые операции
|
|
3. **DataController** - операции с базой данных
|
|
4. **NotificationController** - управление уведомлениями
|
|
5. **CompassController** - управление магнитным компасом
|
|
6. **MapController** - управление картами и переключение между ними
|
|
|
|
### 🎨 **UI Binders (новая архитектура):**
|
|
|
|
1. **MenuBinder** - управление меню и обработка действий
|
|
2. **BottomSheetsBinder** - базовое управление BottomSheet'ами
|
|
3. **BottomSheetsManager** - полное управление BottomSheet'ами с автообновлением
|
|
4. **PermissionsBinder** - управление разрешениями
|
|
|
|
### 🗺️ **Система карт:**
|
|
|
|
- **MapInterface** - единый интерфейс для всех карт
|
|
- **YandexMapImpl** - реализация для Яндекс.Карт
|
|
- **MapLibreMapImpl** - реализация для MapLibre GL
|
|
- **MapForgeImpl** - реализация для MapForge
|
|
- **Strategy Pattern** для переключения между картами
|
|
|
|
### 💾 **Слой данных:**
|
|
|
|
- **Repository Pattern** для работы с данными
|
|
- **Room Database** для персистентности
|
|
- **Entity/Model** разделение для чистоты архитектуры
|
|
- **Mapper** для преобразования между слоями
|
|
|
|
### 🔄 **Паттерны взаимодействия:**
|
|
|
|
- **Observer Pattern** - для уведомлений об изменениях
|
|
- **Command Pattern** - для отложенного выполнения UI операций
|
|
- **Throttling** - для оптимизации производительности
|
|
- **Auto-update** - для автоматического обновления UI
|
|
|
|
### ✅ **Преимущества финальной архитектуры:**
|
|
|
|
1. **Модульность** - каждый компонент можно тестировать и развивать независимо
|
|
2. **Расширяемость** - легко добавлять новые контроллеры и UI компоненты
|
|
3. **Поддерживаемость** - четкое разделение ответственности упрощает поддержку
|
|
4. **Тестируемость** - каждый компонент можно тестировать изолированно
|
|
5. **Производительность** - оптимизированные обновления UI и управление ресурсами
|
|
6. **Гибкость** - возможность переключения между различными реализациями карт
|
|
|
|
### 🎯 **Особенности реализации:**
|
|
|
|
- Гибридный режим GPS (Location API + NMEA)
|
|
- Throttling UI обновлений для производительности
|
|
- Автоматическое управление жизненным циклом компонентов
|
|
- Централизованная обработка ошибок и логирования
|
|
- Поддержка множественных источников данных
|
|
- Система уведомлений с вибрацией и звуком
|