-
Separation of Concerns
- Domain layer: Business logic only, no Android dependencies
- Data layer: Data sources and repository implementations
- Presentation layer: UI components and ViewModels
-
Dependency Rule
- Dependencies point inward (Presentation → Domain ← Data)
- Domain layer must be independent
- No circular dependencies
-
Module Independence
- Each feature module is self-contained
- Communication through domain interfaces
- Shared resources through core modules only
- Purpose: Shared business logic and utilities
- Contains:
- ALL string resources (centralized management)
- Base classes (BaseActivity, BaseFragment, BaseViewModel)
- Common utilities and extensions
- Shared data models
- Animation resources
- Constants and configurations
- Purpose: Reusable UI components and utilities
- Contains:
- Common UI components (EmptyStateView, LoadingDialog, CustomToast)
- UI utilities (DialogUtils, ViewExtensions)
- Third-party UI library dependencies (CRITICAL: ScaleRatingBar)
- Common layouts for reusable components
- Purpose: Visual consistency across the app
- Contains:
- ALL color resources
- ALL drawable resources (icons, backgrounds, selectors)
- Text styles and themes
- Font resources
- Dimension values
- Material Design components configuration
- Purpose: Network infrastructure
- Contains:
- API definitions and interfaces
- Network response models
- Retrofit/OkHttp configuration
- Error handling mechanisms
-
String Resources ✅ IMPLEMENTED
- ALL strings must be in core:common/strings.xml
- No feature-specific string files (feature modules have empty strings.xml)
- Access via:
import com.threedollar.common.R as CommonR - Usage:
getString(CommonR.string.your_string_name) - Use descriptive naming: feature_context_description
- Example: home_search_hint, my_profile_title
Exceptions:
- Manifest-required strings remain in app module (
app_name_3dollar*) - Google Services auto-generated strings remain in app module (
default_web_client_id)
-
Visual Resources
- Colors → core:designsystem/colors.xml
- Drawables → core:designsystem/drawable/
- Styles → core:designsystem/styles.xml
- Never duplicate visual resources
-
UI Components
- Reusable components → core:ui
- Feature-specific layouts → feature/presentation/res/layout/
- Custom views used in multiple features → core:ui
-
Third-party Dependencies
- UI libraries → core:ui (expose as api)
- Example: ScaleRatingBar must be in core:ui only
// core:ui/build.gradle api "com.github.ome450901:SimpleRatingBar:1.5.1"
feature/
├── domain/ # Business logic (no Android dependencies)
│ ├── model/ # Domain models
│ ├── repository/ # Repository interfaces
│ └── usecase/ # Business use cases
├── data/ # Data layer implementation
│ ├── repository/ # Repository implementations
│ ├── datasource/ # Remote/Local data sources
│ └── mapper/ # Data to Domain mappers
└── presentation/ # UI layer
├── ui/ # Activities, Fragments
├── viewmodel/ # ViewModels
├── adapter/ # RecyclerView adapters
└── res/ # ONLY feature-specific layouts
// Feature presentation module dependencies
dependencies {
implementation project(':feature:domain')
implementation project(':core:common') // Strings, base classes
implementation project(':core:ui') // UI components
implementation project(':core:designsystem') // Visual resources
// Android UI dependencies
implementation 'androidx.fragment:fragment-ktx'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx'
// ... other UI dependencies
}Implementation Summary:
- Total files updated: 58+ app module files + feature modules
- Total string references migrated: ~205 references
- String resources centralized: ~450 strings moved to core:common
- Build verification: ✅ Compilation successful
Key Achievements:
- All string resources now in
core:common/strings.xml(Single Source of Truth) - All modules use
CommonR.string.xxxpattern for consistent access - Proper exception handling for manifest and Google Services strings
- Full Clean Architecture compliance maintained
- Zero circular dependencies introduced
Verification Commands:
./gradlew core:common:build # ✅ Success
./gradlew app:build # ✅ Success (lint errors unrelated)- Identify all resources used in the feature
- Check for existing resources in core modules
- List third-party dependencies
- Move strings to core:common ✅ Phase 2-1 COMPLETED
- Move colors/drawables to core:designsystem
- Move shared UI components to core:ui
- Update all resource references ✅ Phase 2-1 COMPLETED
- Update import statements ✅ Phase 2-1 COMPLETED
- Configure module dependencies ✅ Phase 2-1 COMPLETED
- Run
./gradlew build - Verify resource accessibility
- Check layout previews
- Test runtime functionality
- Remove unused resources from app module
-
NEVER create duplicate resources
- Always search existing resources first
- Consolidate similar resources
-
ScaleRatingBar Special Handling
- Only in core:ui module
- Access through module dependency
- Never add directly to feature modules
-
Clean Architecture Compliance
- Domain layer: Pure Kotlin/Java only
- Data layer: Can have Android dependencies
- Presentation: Full Android framework access
-
Resource Naming Conventions
- Strings: feature_context_description
- Layouts: feature_type_name (e.g., home_fragment_main)
- IDs: feature_view_purpose (e.g., home_text_title)
- Adding Android dependencies to domain layer
- Creating feature-specific string files
- Duplicating colors or drawables
- Adding UI libraries directly to feature modules
- Circular dependencies between modules
- Not following the dependency rule
- Clean Architecture by Robert C. Martin
- Android Architecture Components Guide
- Multi-module project best practices