Android常用开发架构(附带真实代码)
字数 1678 2025-08-22 12:22:48
Android常用开发架构详解
1. 开发架构概述
开发架构是指在软件开发中,将应用程序组织成不同组件的方式和规范。它帮助开发人员更好地组织代码、提高可维护性和可扩展性,并促进团队合作。
2. MVC架构
2.1 MVC组件划分
MVC架构将应用程序分为三个主要组件:
- Model(模型):代表应用程序的数据和业务逻辑。负责处理数据的获取、存储、更新和验证,以及执行与数据相关的业务操作。
- View(视图):用户界面的可视部分,负责展示数据给用户,并接收用户的输入。
- Controller(控制器):模型和视图之间的协调者,接收来自视图的用户输入,并根据输入更新模型状态。
2.2 MVC代码实现
控制器实现(TicTacToeActivity)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tictactoe);
winnerPlayerLabel = (TextView) findViewById(R.id.winnerPlayerLabel);
winnerPlayerViewGroup = findViewById(R.id.winnerPlayerViewGroup);
buttonGrid = (ViewGroup) findViewById(R.id.buttonGrid);
model = new Board(); // 创建模型对象
}
public void onCellClicked(View v) {
Button button = (Button) v;
String tag = button.getTag().toString();
int row = Integer.valueOf(tag.substring(0, 1));
int col = Integer.valueOf(tag.substring(1, 2));
Player playerThatMoved = model.mark(row, col); // 调用模型方法
if (playerThatMoved != null) {
button.setText(playerThatMoved.toString()); // 更新视图
if (model.getWinner() != null) {
winnerPlayerLabel.setText(playerThatMoved.toString());
winnerPlayerViewGroup.setVisibility(View.VISIBLE);
}
}
}
模型实现(Board类)
public Player mark(int row, int col) {
Player playerThatMoved = null;
if (isValid(row, col)) {
cells[row][col].setValue(currentTurn);
playerThatMoved = currentTurn;
if (isWinningMoveByPlayer(currentTurn, row, col)) {
state = GameState.FINISHED;
winner = currentTurn;
} else {
flipCurrentTurn(); // 切换当前玩家
}
}
return playerThatMoved;
}
private void flipCurrentTurn() {
currentTurn = (currentTurn == Player.X) ? Player.O : Player.X;
}
public void restart() {
clearCells();
winner = null;
currentTurn = Player.X;
state = GameState.IN_PROGRESS;
}
2.3 MVC架构的不足
- 视图和控制器之间的耦合度较高
- 视图承担了过多的职责(显示+处理交互)
- 控制器变得臃肿,难以管理
- 界面逻辑与业务逻辑耦合在一起
3. MVP架构
3.1 MVP组件划分
MVP架构将应用程序分为三个主要组件:
- Model(模型):与MVC中的模型类似,负责数据和业务逻辑
- View(视图):负责展示数据和接收用户输入,通过接口与Presenter通信
- Presenter(表示器):作为View和Model之间的桥梁,处理业务逻辑
3.2 MVP代码实现
View接口定义
public interface TicTacToeView {
void showWinner(String winningPlayerDisplayLabel);
void clearWinnerDisplay();
void clearButtons();
void setButtonText(int row, int col, String text);
}
Activity实现View接口
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tictactoe);
winnerPlayerLabel = (TextView) findViewById(R.id.winnerPlayerLabel);
winnerPlayerViewGroup = findViewById(R.id.winnerPlayerViewGroup);
buttonGrid = (ViewGroup) findViewById(R.id.buttonGrid);
presenter.onCreate();
}
public void onCellClicked(View v) {
Button button = (Button) v;
String tag = button.getTag().toString();
int row = Integer.valueOf(tag.substring(0, 1));
int col = Integer.valueOf(tag.substring(1, 2));
presenter.onButtonSelected(row, col); // 调用Presenter方法
}
@Override
public void setButtonText(int row, int col, String text) {
Button btn = (Button) buttonGrid.findViewWithTag("" + row + col);
if (btn != null) {
btn.setText(text);
}
}
Presenter实现
public void onButtonSelected(int row, int col) {
Player playerThatMoved = model.mark(row, col); // 调用模型
if (playerThatMoved != null) {
view.setButtonText(row, col, playerThatMoved.toString()); // 更新视图
if (model.getWinner() != null) {
view.showWinner(playerThatMoved.toString());
}
}
}
3.3 MVP架构的优势
- 明确划分了视图、业务逻辑和Presenter的责任
- 通过接口将视图和Presenter解耦
- 业务逻辑集中在Presenter中,便于测试
- 视图只负责展示和用户交互,职责单一
3.4 MVP架构的不足
- 需要手动进行视图和Presenter之间的数据同步
- 复杂场景下Presenter可能变得臃肿
- 通信模式是单向的(视图→Presenter),不够灵活
4. MVVM架构
4.1 MVVM组件划分
MVVM架构由三个主要组件组成:
- Model(模型):负责处理数据和业务逻辑
- View(视图):负责展示数据和与用户交互
- ViewModel:连接View和Model,负责管理视图状态和逻辑
4.2 MVVM配置
在build.gradle中启用Data Binding:
android {
dataBinding {
enabled = true
}
}
在布局文件中绑定ViewModel:
<data>
<import type="android.view.View" />
<variable name="viewModel" type="com.acme.tictactoe.viewmodel.TicTacToeViewModel" />
</data>
4.3 MVVM代码实现
Activity实现
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TictactoeBinding binding = DataBindingUtil.setContentView(this, R.layout.tictactoe);
binding.setViewModel(viewModel); // 绑定ViewModel
viewModel.onCreate();
}
ViewModel实现
public void onClickedCellAt(int row, int col) {
Player playerThatMoved = model.mark(row, col); // 调用模型
cells.put("" + row + col, playerThatMoved == null ? null : playerThatMoved.toString());
winner.set(model.getWinner() == null ? null : model.getWinner().toString());
}
模型实现
public Player mark(int row, int col) {
Player playerThatMoved = null;
if (isValid(row, col)) {
cells[row][col].setValue(currentTurn);
playerThatMoved = currentTurn;
if (isWinningMoveByPlayer(currentTurn, row, col)) {
state = GameState.FINISHED;
winner = currentTurn;
} else {
flipCurrentTurn();
}
}
return playerThatMoved;
}
4.4 MVVM架构的优势
- 通过数据绑定实现视图和ViewModel的自动同步
- 双向绑定机制简化了视图更新
- ViewModel集中管理视图状态和逻辑
- 支持数据驱动的开发方式
4.5 MVVM架构的不足
- 过度使用数据绑定可能导致代码复杂
- ViewModel设计不当可能变得臃肿
- 双向绑定可能带来性能问题
- 需要引入特定框架,增加项目依赖性
5. 架构对比总结
| 特性 | MVC | MVP | MVVM |
|---|---|---|---|
| 视图职责 | 显示+交互 | 显示+交互(通过接口) | 主要显示 |
| 业务逻辑位置 | 分散在Controller和Model | 集中在Presenter | 集中在ViewModel |
| 耦合度 | 视图和控制器高耦合 | 视图和Presenter解耦 | 视图和ViewModel解耦 |
| 数据绑定 | 无 | 无 | 支持双向绑定 |
| 测试便利性 | 较差 | 较好 | 最好 |
| 适合场景 | 简单应用 | 中等复杂度应用 | 复杂应用 |
6. 架构选择建议
- 简单应用:可以考虑使用MVC,结构简单直接
- 中等复杂度应用:推荐使用MVP,职责分离清晰
- 复杂应用:建议使用MVVM,特别是需要数据绑定和响应式UI的场景
- 团队协作项目:MVP或MVVM更合适,便于分工和测试
- 已有架构迁移:考虑团队熟悉度和迁移成本
选择架构时还应考虑团队的技术栈熟悉度、项目规模和长期维护需求等因素。