Architecture & Tech choices - Fabryo/PokeManiac GitHub Wiki
Architecture
The application is developed using a modular architecture that follows the Android Architecture Components principles. This structure ensures the scalability of the app when new features need to be added.
Module Dependency Diagram
flowchart TD
%% Global style for dark mode
classDef darkMode fill:#000000,stroke:#FFFFFF,stroke-width:2px,color:#FFFFFF;
subgraph Presentation_Layer
direction TB
App["App (Main entry)"]
Dashboard["Dashboard Feature"]
SearchFriends["SearchFriends Feature"]
MyFriends["MyFriends Feature"]
MyProfile["MyProfile Feature"]
NewPost["NewPost Feature"]
CoreUI["CoreUI Module (Shared Compose Views)"]
end
subgraph Domain_Layer
direction TB
Domain["Domain (Repository Interfaces + Entities)"]
end
subgraph Data_Layer
direction TB
Data["Data Module (Repository Implementations)"]
Api["API Module (Networking Services)"]
Database["Database Module (Room Persistence)"]
end
subgraph Tracking_Layer
Tracking["Tracking Module (Analytics + Events Storage)"]
end
%% -- Flows inside Presentation Layer
App --> Dashboard
App --> SearchFriends
App --> MyFriends
App --> MyProfile
App --> NewPost
App --> CoreUI
Dashboard --> CoreUI
SearchFriends --> CoreUI
MyFriends --> CoreUI
MyProfile --> CoreUI
NewPost --> CoreUI
%% -- External Flows
Presentation_Layer --> Domain_Layer
Presentation_Layer --> Tracking_Layer
Tracking_Layer --> Domain_Layer
Data_Layer --> Domain_Layer
Database --> Data
%% Apply dark mode style
linkStyle default stroke:#FFFFFF,stroke-width:1.5px
class App,Dashboard,SearchFriends,MyFriends,MyProfile,NewPost,CoreUI,Domain,Data,Api,Database,Tracking darkMode
The implemented modules are:
- App module: the main entry point of the application. It also contains the Splash and SignIn/SignUp screens.
- One module per Dynamic Feature, such as:
- Dashboard: the news feed where all transactions from the user’s friends (and the user) appear.
- SearchFriends: the feature for finding friends.
- MyFriends: the feature to browse your friend list and view detailed one-to-one transaction history.
- MyProfile: the user’s profile feature.
- NewPost: the feature to create and share new posts.
- CoreUI module: contains shared Compose Views, resources, and utilities used across feature modules.
All UI modules follow the MVVM design pattern, with ViewModels exposing state objects. All screens are implemented using Jetpack Compose. All Features contain one Activity accessible from the other Features. The Navigation inside each feature (module) is made with the Compose Navigation.
Additional layers include:
- Domain module, containing:
- Repository interfaces
- Model Entities
- Note : Choice was made not to implement UseCases and to call the Repositories directly from the ViewModels. Indeed, introducing UseCases would add unnecessary complexity and boilerplate in a context where the features are relatively simple.
- Data module, containing:
- Request interfaces
- Repository implementations
- Api module: introduced to separate networking logic from the rest of the data layer. It includes:
- The HTTP client and API services
- API request implementations
- Database module: separates local persistence logic (implemented with Room) from the rest of the data layer.
- Tracking module: allows integration of third-party libraries for analytics and user tracking. The goal is to monitor feature usage and leverage this data to make meaningful decisions about future app evolution. All Presentation modules implement the Tracking module.
- Dependenty Injection Module: allows the presentation layer to have knowledge only of the domain layer module, and not of the data layer modules to respect the Clean Architecture principles.
Architecture Data Flow
flowchart TD
%% Global style for dark mode
classDef darkMode fill:#000000,stroke:#FFFFFF,stroke-width:2px,color:#FFFFFF;
subgraph Presentation_Module
direction TB
Activity["Activity / Composable"]
ViewModel["ViewModel"]
end
subgraph Domain_Module
direction TB
RepositoryInterface["Repository Interface"]
end
subgraph Data_Module
direction TB
RepositoryImpl["Repository Implementation"]
RequestInterface["Request Interface"]
DataStoreInterface["DataStore Interface"]
end
subgraph Database_Module
direction TB
DataStoreImpl["DataStore Implementation"]
RoomDatabase["Room Database"]
end
subgraph API_Module
direction TB
RequestImpl["Request Implementation"]
end
subgraph External_Services
direction TB
RemoteApi["Remote API"]
end
%% Calls (flow top-down)
Activity -->|User Actions| ViewModel
ViewModel -->|Call Repository| Domain_Module
RepositoryInterface -->|Implementation| RepositoryImpl
RepositoryImpl -->|Fetch Remote Data| RequestInterface
RepositoryImpl -->|Fetch Local Data| DataStoreInterface
RequestInterface -->|Implementation| RequestImpl
DataStoreInterface --> |Implementation| DataStoreImpl
RequestImpl -->|Call External API| RemoteApi
DataStoreImpl -->|Fetch Local Data| RoomDatabase
%% Responses (horizontal dotted lines, no "up")
ViewModel -.->|StateFlow/SharedFlow| Activity
Domain_Module -.->|Flow Data| ViewModel
RemoteApi -.->|API Response| RequestImpl
RoomDatabase -.->|Flow DB Entities| DataStoreImpl
RequestInterface -.->|Remote Data| RepositoryImpl
DataStoreInterface -.->|Flow Local Data| RepositoryImpl
%% Styling for dark mode
linkStyle default stroke:#FFFFFF,stroke-width:1.5px
class Activity,ViewModel,RepositoryInterface,RepositoryImpl,RequestInterface,DataStoreInterface,RequestImpl,DataStoreImpl,RoomDatabase,RemoteApi darkMode
Tech choices
The application is built using the following libraries:
- Kotlin as the language for all layers
- Jetpack Compose for the UI and ViewModel for the UI-related data storage and logic handle
- Material3 and AndroidX for design components, views, icons, and lifecycle management
- Coroutines and Flow to handle the data flow from the data-api-database modules to the ViewModels and UI subscriptions
- Compose Navigation for all navigation between Compose Screens inside a Feature
- Flow (StateFlow and SharedFlow) to expose states and events from ViewModels to screens
- Coil for image loading
- Koin for dependency injection
- SquareUp Retrofit & OkHttp3 & Moshi for remote API calls and JSON parsing
- Room for local database implementation
- JUnit, Mockito, Koin-Test, and Espresso for testing