android/java项目常见的项目结构
最合理、最现代的项目结构是:以“按功能/模块分包”为主,顶层辅以datadomaindi等共享模块,并结合MVVM等清晰架构进行组织。给你的建议:从按功能分包开始:即使是新项目,也立即采用这种结构。不要等到项目复杂了再重构。功能划分粒度:功能的划分要合理。例如login(登录)、home(首页)、profile(个人资料)、settings(设置)都是典型的功能模块。提取共享层:将datadoma
1. 标准Gradle项目结构(基础)
当你创建一个新的Android项目时,Android Studio会默认生成一个基于Gradle的结构。这是所有结构的基础。
MyApp/
├── app/ # 主模块(Module)
│ ├── build.gradle # 模块级别的Gradle构建脚本(最重要)
│ ├── src/
│ │ ├── main/ # 主源代码目录
│ │ │ ├── java/ # Java/Kotlin 源代码
│ │ │ │ └── com/example/myapp/ # 你的包名
│ │ │ ├── res/ # 资源文件(layout, drawable, values等)
│ │ │ └── AndroidManifest.xml
│ │ └── androidTest/ # Android仪器化测试
│ │ └── test/ # 本地单元测试(运行在JVM上)
│ └── proguard-rules.pro
├── gradle/
├── build.gradle # 项目级别的Gradle构建脚本
└── settings.gradle # 定义项目包含哪些模块
关键点:
src/main/java
是核心代码所在地。问题就在于如何组织这个包下的代码。src/test
和src/androidTest
的目录结构应该与main
下的结构一一镜像,这样便于找到对应类的测试。
2. “按层分包” (By Layer) - 传统但不推荐
早期Android项目常用这种方式,按代码的“类型”或“层级”划分包。
com.example.myapp/
├── activity/
│ ├── MainActivity.java
│ └── DetailActivity.java
├── adapter/
│ └── MyListAdapter.java
├── fragment/
│ └── HomeFragment.java
├── model/
│ └── User.java
├── service/
│ └── ApiService.java
└── utils/
└── DateUtils.java
缺点:
- 难以扩展和维护:当项目变大时,每个包下的文件数量会爆炸式增长,找一个文件非常困难。
- 功能内聚性差:一个完整的“用户详情”功能可能分散在
activity
,fragment
,adapter
,model
等多个包中,无法一眼看出哪些代码属于同一个功能。 - 不利于模块化:这种结构很难抽离出一个独立的功能模块。
3. “按功能/模块分包” (By Feature) - 当前最佳实践
这是目前最受推崇的结构。它将所有属于同一功能的代码
这种结构的核心思想是:将属于同一业务功能的所有代码聚集在一起,而不是将同一类型的代码(Activity, Fragment, ViewModel, Repository等)放在同一个包下。顶层辅以一些共享的、与功能无关的通用包。
以下是一个典型且高度推荐的结构:
<你的包名,如 com.company.app>/
│
├── di/ # 【共享】依赖注入模块 (Dagger Hilt/Koin)
│ ├── AppComponent.java
│ ├── AppModule.java
│ └── ViewModelModule.java
│
├── data/ # 【共享】数据层
│ ├── local/ # 本地数据源 (数据库、文件、Preferences)
│ │ ├── dao/ # Room Dao 接口
│ │ └── entity/ # Room 实体类
│ ├── remote/ # 远程数据源 (网络)
│ │ ├── api/ # Retrofit 接口
│ │ ├── dto/ # 网络传输数据对象 (Data Transfer Object)
│ │ └── interceptor/ # OkHttp 拦截器
│ └── repository/ # 仓库实现类
│ ├── UserRepositoryImpl.java
│ └── SettingsRepositoryImpl.java
│
├── domain/ # 【共享】领域层 (可选但强烈推荐)
│ ├── model/ # 业务核心模型/实体 (Entity)
│ ├── repository/ # 仓库接口定义
│ └── usecase/ # 用例/交互器 (Use Cases)
│ ├── GetUserUseCase.java
│ └── LoginUserUseCase.java
│
├── core/ # 【共享】核心工具和基础组件
│ ├── util/ # 通用工具类 (避免上帝类,按功能细分)
│ ├── extensions/ # Kotlin 扩展函数
│ ├── base/ # 基类 (BaseActivity, BaseFragment, BaseViewModel)
│ └── common/ # 常量、配置等
│
├── feature_a/ # 【功能模块A】例如: auth, home, profile, settings
│ ├── ui/ # UI 相关组件
│ │ ├── FeatureAActivity.java
│ │ ├── FeatureAFragment.java
│ │ ├── FeatureAViewModel.java # ViewModel
│ │ └── adapter/ # 功能专用的适配器
│ │ └── view/ # 自定义View
│ └── model/ # 功能专用的呈现模型 (Presentation Model)
│ └── FeatureAUiState.java # 或 Vo (Value Object)
│
├── feature_b/ # 【功能模块B】
│ └── ui/
│ └── ...
│
└── app/ # 应用的入口 (可选的包)
└── MainActivity.java # 通常是最初的启动Activity
优点:
-
- 高内聚,低耦合 (High Cohesion, Low Coupling)
- 内聚性:所有与“用户资料”相关的代码(Activity, ViewModel, 状态类)都在
feature_profile
包里。修改一个功能时,你只需要关注一个目录。 - 耦合性:功能模块之间不直接依赖,而是通过顶层共享的
domain
(接口)和data
层进行通信,使得模块独立性更强。
-
极大的可维护性和可读性
- 新成员加入项目,可以很快地根据功能名称找到相关代码。
- 导航代码库变得非常直观,不再需要在天花乱坠的
adapter
,fragment
包中大海捞针。
-
为模块化铺平道路
- 这是该结构最大的优势之一。当项目变得庞大时,你可以轻松地将每个
feature_*
包提取到一个独立的 Android Library Module 中。 - 模块化可以显著改善构建时间,实现团队并行开发,并严格强制模块间的边界。从这种结构开始,迁移到完全模块化的成本最低。
- 这是该结构最大的优势之一。当项目变得庞大时,你可以轻松地将每个
-
与现代架构完美契合
- 这种结构天然地适配 MVVM、MVI 等模式。每个功能包内的
ui
子包就对应了 MVVM 中的 View 和 ViewModel。
- 这种结构天然地适配 MVVM、MVI 等模式。每个功能包内的
4. 结合架构组件(MVVM)的清晰结构
上面的“按功能分包”完美契合了流行的 MVVM(Model-View-ViewModel) 架构。
在一个功能包内(例如 feature_user
),结构可以是这样:
feature_user/
├── UserActivity.java # View层 (Activity/Fragment)
├── UserViewModel.java # ViewModel层 (继承自ViewModel)
├── UserRepository.java # 仓库接口(在domain层或本地定义)
├── ui/ # 可选的更细化的UI包
│ ├── UserAdapter.java
│ └── UserItemDecoration.java
└── model/ # 该功能专用的模型(Vo)
└── UserVo.java
各层职责:
- View (
Activity
/Fragment
): 处理UI显示和用户输入,向ViewModel请求数据。 - ViewModel: 为View准备数据,处理业务逻辑,调用UseCase或Repository。
- Repository: 数据仓库,协调多个数据源(本地、远程),是唯一的数据入口。
- Model: 实体类,代表核心数据。
5. "按功能"与传统“按层分包”的对比
特性 | 按层分包 (By Layer) | 按功能分包 (By Feature) |
---|---|---|
结构 | ui/ , model/ , adapter/ |
feature_a/ , feature_b/ , data/ |
可查找性 | 差。需记得类类型才能查找。 | 优秀。根据功能名直接定位。 |
内聚性 | 低。相关代码分散各处。 | 高。功能代码集中管理。 |
可维护性 | 项目变大后极难维护。 | 易于维护和扩展。 |
模块化准备 | 很难重构为模块。 | 极易迁移到模块化。 |
团队协作 | 容易在通用包上产生冲突。 | 冲突少。每人负责不同功能模块。 |
6. 总结与最终建议
最合理、最现代的项目结构是:
以“按功能/模块分包”为主,顶层辅以
data
,domain
,di
等共享模块,并结合MVVM等清晰架构进行组织。
给你的建议:
- 从按功能分包开始:即使是新项目,也立即采用这种结构。不要等到项目复杂了再重构。
- 功能划分粒度:功能的划分要合理。例如
login
(登录)、home
(首页)、profile
(个人资料)、settings
(设置)都是典型的功能模块。 - 提取共享层:将
data
,domain
(包含Repository接口和UseCase),di
放在顶层,供所有功能模块使用。 - 保持测试结构镜像:为每个功能类编写测试,并确保测试文件位于
test
和androidTest
中对应的包路径下。 - 命名清晰:功能包的名字要能清晰表达其业务含义。
- 为模块化做准备:在代码组织上就假设每个功能未来都是一个独立模块,避免产生跨功能的直接依赖。使用 Dagger Hilt 或 Koin 等依赖注入框架来管理依赖关系,这对模块化至关重要。
总而言之,放弃传统的按层分包,拥抱按功能分包 + 分层架构,是现代 Android 开发中最重要的项目结构最佳实践。
更多推荐
所有评论(0)