如何将基础Android示例应用适配为MVP架构模式?
刚好拿这个简单的文本复制App来入门MVP太合适了!咱们一步步拆解,把它改成标准的MVP架构——先明确MVP的核心分工:Model负责数据/业务处理、View负责UI展示与用户交互、Presenter作为中间层,连接Model和View,处理逻辑调度,三者互不直接耦合。
先看看你的原代码:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void sendMessage(View view) { //Grab input EditText editText = findViewById(R.id.editText); String message = editText.getText().toString(); //Throw input onto the label TextView destinationText = findViewById(R.id.destinationText); destinationText.setText(message); } }
下面是具体的适配步骤:
1. 定义View接口(MainView)
MVP里,View需要通过接口向Presenter暴露它能完成的UI操作,避免Presenter直接操作UI控件。这里我们的View只需要做两件事:获取用户输入、展示结果文本,所以定义接口:
public interface MainView { // 获取EditText中的用户输入 String getInputText(); // 将结果显示到TextView void showResultText(String text); }
2. 实现Model层(MainModel)
Model是数据和业务逻辑的载体,哪怕现在只是简单的文本传递,也要抽离出来——方便后续扩展(比如加文本非空验证、格式化、存储等):
public class MainModel { // 这里可以添加业务逻辑,比如文本校验、加工 public String processInputText(String inputText) { // 示例:后续可以加空值判断 // if (inputText.trim().isEmpty()) { // throw new IllegalArgumentException("输入文本不能为空"); // } return inputText; } }
3. 编写Presenter层(MainPresenter)
Presenter是核心调度者,持有View和Model的引用,负责把用户交互传递给Model处理,再把处理结果通知View更新:
public class MainPresenter { private MainView view; private MainModel model; public MainPresenter(MainView view) { this.view = view; this.model = new MainModel(); } // 处理按钮点击的逻辑 public void onSendMessageButtonClicked() { // 从View获取输入 String userInput = view.getInputText(); // 交给Model处理 String processedText = model.processInputText(userInput); // 通知View展示结果 view.showResultText(processedText); } }
4. 修改MainActivity作为View的实现
现在Activity只需要专注于UI相关的工作,业务逻辑全部交给Presenter:
public class MainActivity extends AppCompatActivity implements MainView { private MainPresenter presenter; private EditText editText; private TextView destinationText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化UI控件 editText = findViewById(R.id.editText); destinationText = findViewById(R.id.destinationText); // 创建Presenter,把当前View实例传递进去 presenter = new MainPresenter(this); } // 按钮点击的回调方法,直接转交给Presenter处理 public void sendMessage(View view) { presenter.onSendMessageButtonClicked(); } // 实现MainView的接口方法:获取输入文本 @Override public String getInputText() { return editText.getText().toString(); } // 实现MainView的接口方法:展示结果文本 @Override public void showResultText(String text) { destinationText.setText(text); } }
这么拆分的好处:
- 解耦:Activity不再混杂业务逻辑,只做UI的事;Presenter和UI完全无关,方便后续替换UI(比如换成Fragment);Model独立处理数据,不受UI变化影响。
- 可测试性:Presenter和Model都可以脱离Android环境写单元测试,不用依赖模拟器或真机。
- 扩展性:如果后续要加功能(比如输入文本长度限制、保存到本地),只需要修改Model层;如果要优化UI逻辑,只需要调整View层,互不干扰。
内容的提问来源于stack exchange,提问作者MacInnis
相关产品推荐
相关产品推荐

