Android MVVM文件结构:MVVM/MVP需按组件划分包还是仅逻辑结构?
Great question—this is something a lot of devs grapple with when first adopting MVVM or MVP on Android. Let’s break this down clearly:
1. Using Explicit Model/ViewModel/View Packages
Many teams choose to structure their codebase with dedicated model, viewmodel, view (or ui for views) packages, and here’s why:
- Clear boundaries: It makes it immediately obvious where each component lives. New team members can quickly navigate to the layer they need to work on without guessing.
- Enforces architecture rules: Physical separation makes it harder to accidentally introduce tight coupling (like a View directly accessing a Model instead of going through a ViewModel).
- Scalability: As your app grows, having these dedicated packages keeps things organized. You can even sub-divide them further (e.g.,
model/user,viewmodel/dashboard) as features expand.
For example, a typical structure might look like this:
com.yourapp ├── model │ ├── User.kt │ ├── Product.kt │ └── repositories │ └── UserRepository.kt ├── viewmodel │ ├── DashboardViewModel.kt │ └── ProfileViewModel.kt └── view ├── activities │ └── MainActivity.kt └── fragments ├── DashboardFragment.kt └── ProfileFragment.kt
2. Logical Separation Without Dedicated Packages
Some teams opt to skip the top-level model/viewmodel/view packages and instead organize by feature first, with architecture layers nested inside each feature. This is often called "feature-first" structure, and it’s totally valid too:
- Feature-centric focus: If your app is built around distinct features (e.g., Dashboard, Profile, Cart), grouping all related components (Model, ViewModel, View) under a feature package makes it easier to work on a single feature without jumping across multiple top-level packages.
- Modularity: It simplifies extracting a feature into a separate module later, since all its components are already grouped together.
An example of this structure:
com.yourapp ├── dashboard │ ├── DashboardFragment.kt │ ├── DashboardViewModel.kt │ └── DashboardModel.kt ├── profile │ ├── ProfileFragment.kt │ ├── ProfileViewModel.kt │ └── User.kt └── core └── base ├── BaseViewModel.kt └── BaseFragment.kt
So Which Should You Choose?
There’s no one-size-fits-all answer, but here are some guidelines:
- If you’re working on a small app or just starting with MVVM/MVP, starting with explicit
model/viewmodel/viewpackages can help you learn and enforce the architecture boundaries clearly. - If your app is large or has distinct, independent features, a feature-first structure with nested layers is usually more maintainable—it keeps related code together and reduces cognitive load when working on a single feature.
- The key is consistency: Whatever structure you pick, stick with it across your team. The architecture’s purpose is to keep code organized and maintainable, so the structure should serve that goal, not the other way around.
Remember, MVVM/MVP are architectural patterns—they define how components interact, not necessarily how you package them. Both physical package separation and logical separation can work, as long as you follow the core principles:
- Views observe ViewModels (MVVM) or interact with Presenters (MVP)
- ViewModels/Presenters handle business logic and communicate with Models/Repositories
- Models handle data and business rules
内容的提问来源于stack exchange,提问作者Jakub Kwiatek




