单一职责原则:用MVP模式为Activity解耦

前端之家收集整理的这篇文章主要介绍了单一职责原则:用MVP模式为Activity解耦前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、什么是单一职责原则

单一职责原则(SRP:Single responsibility principle)又称单一功能原则,其定义为:一个类,应该只有一个可以导致变化的原因。光看概念会让人很头疼,我先讲点小例子吧:

二、单一职责原则能解决什么问题

回顾我们的 Android 开发经历,很多人都会发现 Activity 类中的代码总会不知不觉地变得很多,这会让读我们代码的人非常痛苦。而造成这种情况的其中一个原因是:Activity 中需要与用户进行大量的交互,用户的操作会改变 Activity 当前显示的界面元素/对应的信息,所以我们总会把 Model、View、点击事件等等……操作全都放到了 Activiy 中,但这样存在一个很严重的问题,无脑地为 Activity 添加代码,势必让 Activity 变得臃肿,结构混乱,职责模糊,特别是之前负责该项目的工程师已经离职,新入职的工程师需要重构该 Activity 时,必将痛不欲生。

那么我们要怎样为 Activity 解耦呢?我先通过一个小 Demo 以单一职责原则的思想为 Activity 解耦,详情如下:

  1. public class Data {
  2. private String btn1Str = "btn1 Clicked 1";
  3. private String btn2Str = "btn2 Clicked 1";
  4. private String btn3Str = "btn3 Clicked 1";
  5. private String btn4Str = "btn4 Clicked 1";
  6.  
  7. public String getData(int index){
  8. if(index == 1)
  9. return btn1Str;
  10. else if(index == 2)
  11. return btn2Str;
  12. else if(index == 3)
  13. return btn3Str;
  14. else
  15. return btn4Str;
  16. }
  17.  
  18. public void setData(int index,String str){
  19. if(index == 1)
  20. btn1Str = str;
  21. else if(index == 2)
  22. btn2Str = str;
  23. else if(index == 3)
  24. btn3Str = str;
  25. else
  26. btn4Str = str;
  27. }
  28. }
  1. import android.app.Activity;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.view.View.OnClickListener;
  5. import android.widget.Button;
  6.  
  7.  
  8. public class MainActivity extends Activity implements OnClickListener{
  9. private Button btn1;
  10. private Button btn2;
  11. private Button btn3;
  12. private Button btn4;
  13.  
  14. private Data data = new Data();
  15.  
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20.  
  21. btn1 = (Button)findViewById(R.id.button1);
  22. btn2 = (Button)findViewById(R.id.button2);
  23. btn3 = (Button)findViewById(R.id.button3);
  24. btn4 = (Button)findViewById(R.id.button4);
  25.  
  26. btn1.setOnClickListener(this);
  27. btn2.setOnClickListener(this);
  28. btn3.setOnClickListener(this);
  29. btn4.setOnClickListener(this);
  30. }
  31.  
  32. public void updateData(){
  33. //各种网络请求操作更新数据
  34. }
  35.  
  36. @Override
  37. public void onClick(View v) {
  38. switch(v.getId()){
  39. case R.id.button1:
  40. btn1.setText(data.getData(1));
  41. break;
  42.  
  43. case R.id.button2:
  44. btn2.setText(data.getData(2));
  45. break;
  46.  
  47. case R.id.button3:
  48. btn3.setText(data.getData(3));
  49. break;
  50.  
  51. case R.id.button4:
  52. btn4.setText(data.getData(4));
  53. break;
  54. }
  55. }
  56. }

在 Demo 里我们可以看到,所有相关的操作都在 Activity 里进行,要知道,这还只是一个非常简单的页面,可以说完全不存在业务逻辑。换成一个业务逻辑复杂的页面,这还用玩?接下来换一个思路,用 MVP 模式解耦:

  1. public class Presenter {
  2. private Data data;
  3. private IView iView;
  4.  
  5. public Presenter(IView iView) {
  6. this.iView = iView;
  7. data = new Data();
  8. }
  9.  
  10. public Data getData(){
  11. return data;
  12. }
  13.  
  14. public void setData(int index,String str){
  15. //各种网络请求更新数据
  16. data.setData(index,str);
  17. updateView();
  18. }
  19.  
  20. private void updateView(){
  21. iView.updateView(data);
  22. }
  23. }
  1. public interface IView {
  2. public void updateView(Data data);
  3. }
  1. import android.app.Activity;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.view.View.OnClickListener;
  5. import android.widget.Button;
  6.  
  7.  
  8. public class MainActivity extends Activity implements IView,OnClickListener{
  9. private Button btn1;
  10. private Button btn2;
  11. private Button btn3;
  12. private Button btn4;
  13.  
  14. private Presenter presenter;
  15.  
  16. private Data data = new Data();
  17.  
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.activity_main);
  22.  
  23. btn1 = (Button)findViewById(R.id.button1);
  24. btn2 = (Button)findViewById(R.id.button2);
  25. btn3 = (Button)findViewById(R.id.button3);
  26. btn4 = (Button)findViewById(R.id.button4);
  27.  
  28. btn1.setOnClickListener(this);
  29. btn2.setOnClickListener(this);
  30. btn3.setOnClickListener(this);
  31. btn4.setOnClickListener(this);
  32.  
  33. presenter = new Presenter(this);
  34. }
  35.  
  36. @Override
  37. public void updateView(Data data) {
  38. this.data = data;
  39. }
  40.  
  41. @Override
  42. public void onClick(View v) {
  43. switch(v.getId()){
  44. case R.id.button1:
  45. btn1.setText(data.getData(1));
  46. break;
  47.  
  48. case R.id.button2:
  49. btn2.setText(data.getData(2));
  50. break;
  51.  
  52. case R.id.button3:
  53. btn3.setText(data.getData(3));
  54. break;
  55.  
  56. case R.id.button4:
  57. btn4.setText(data.getData(4));
  58. break;
  59. }
  60. }
  61. }

进行这样的重构之后,Activity 类发生了什么变化呢?我们先回想下 Android SDK 对 Activity 的定义吧:

An activity is a single,focused thing that the user can do. Almost all activities interact with the user,so the Activity class takes care of creating a window for you in which you can place your UI with {@link #setContentView}. While activities are often presented to the user as full-screen windows,they can also be used in other ways: as floating windows (via a theme with {@link android.R.attr#windowIsFloating} set) or embedded inside of another activity (using {@link ActivityGroup}).

简单翻译下:Activity 象征用户能完成的一件事,大部分 Activity 用于和用户进行交互,在其中放置我们的 UI。

也就是说,Google 官方认为 Activity 的职责是:呈现 UI,与用户交互。

那么之前的代码很显然违反了单一职责原则了,因为在 Activity 中不但要进行数据的请求和更新、根据用户的交互/更新的数据去修改 View。那么新代码让 Activity 发生了什么改变呢?第一、数据的请求/更新由 Presenter 处理,不需要经过 Activity 去请求/更新;第二、View 相关的逻辑(如:修改)由 IView 接口提供,Activity 只需要完成具体实现。

三、遵循单一职责原则有什么好处

那么进行这样的重构有什么好处呢?我相信看了示例之后,大家心里多少会有些说不清、道不明的触动,特别是回忆起过去写的一些结构糟糕的代码时触动会更深些。实际上,我个人认为设计模式中的思想和生活中高效组织、完成工作的思想都是一致的,因为所谓设计模式,本身就是前人对写代码的经验总结,其目的就在于:提高效率,便于维护,让代码易读,易拓展等等……回顾生活,我们要想让一个团队/组织/公司/企业高效运作,那么这个群体就得根据实际划分部门 —> 确立部门沟通规范 —> 部门内再次进行团队职责细分(例如 UI 部门分为:视觉设计、交互设计等等……) —> 部门成员明确分工,尽可能让整个群体结构呈现为模块化、低耦合、高内聚、职责区分清晰的结构。

而单一职责原则体现的也是这样的思想,一个类,应该只受其最根本的抽象逻辑影响,类内的具体变化都应该来自于该抽象逻辑,我们说单一职责,我认为其含义不在于一个类做一件事,而在于一个类就是一个抽象群体,抽象群体具有自身的属性和职责,它的职责可能需要它做很多事,但它的职责始终唯一

进行这样的重构之后我们可以把类内不属于它的逻辑剥离出去,让类遵循它的抽象逻辑,而不需要为其他不属于它的职责增加代码

猜你在找的设计模式相关文章