Android开发中,有3种常见的开发模式
1、MVC (Model-View-Controller):
Model(模型):负责数据和业务逻辑的处理。
View(视图):负责显示数据(用户界面)和接收用户操作。
Controller(控制器):充当模型和视图之间的中介,控制用户输入并调用模型和视图进行更新。
2、MVP (Model-View-Presenter):
Model:同MVC,负责数据处理和业务逻辑。
View:定义界面元素以及它们之间的交互,但不包含业务逻辑。
Presenter:充当View和Model之间的桥梁,处理业务逻辑并更新View。
3、MVVM (Model-View-ViewModel):安卓主推
Model:负责数据管理和业务逻辑。
View:定义用户界面,不包含业务逻辑。
ViewModel:包含View的业务逻辑,从Model中获取数据并提供给View,响应View的交互。
示例1:MVC
通过一个简单的安卓天气应用来说明MVC(Model-View-Controller)模式是如何工作的。
1.1 Model(数据模型)
在MVC模式中,模型负责处理应用程序的数据和业务逻辑。对于天气应用,模型可能包括以下几个部分:
- WeatherRepository:一个类,负责与网络API通信,获取天气数据。
- WeatherModel:一个数据类,代表天气信息,比如温度、湿度、风速等。
public class WeatherRepository {public WeatherModel getWeather(String city) {// 这里会调用网络API获取天气数据,并返回一个WeatherModel对象// 为了简化,我们假设直接返回一个WeatherModel实例return new WeatherModel("晴", 25, 30, "北风3级");}
}public class WeatherModel {private String condition;private int temperature;private int humidity;private String wind;// 构造函数、getter和setter省略
}
1.2 View(视图)
视图负责显示数据(用户界面)和接收用户操作。在天气应用中,视图可能包括:
- WeatherActivity:一个Activity,作为用户界面的入口点。
- XML布局文件:定义了天气信息展示的界面元素,如TextView来显示天气状况、温度等。
<!-- activity_weather.xml -->
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/cityName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="City Name"android:textSize="24sp" /><TextViewandroid:id="@+id/weatherCondition"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Weather Condition"android:textSize="18sp" /><TextViewandroid:id="@+id/temperature"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Temperature"android:textSize="18sp" /><!-- 其他界面元素 -->
</LinearLayout>
public class WeatherActivity extends AppCompatActivity {private TextView cityNameView;private TextView weatherConditionView;private TextView temperatureView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_weather);cityNameView = findViewById(R.id.cityName);weatherConditionView = findViewById(R.id.weatherCondition);temperatureView = findViewById(R.id.temperature);WeatherController weatherController = new WeatherController(this, "北京");weatherController.updateWeather();}
}
1.3 Controller(控制器)
控制器负责处理用户输入并调用模型和视图进行更新。在天气应用中,控制器可能包括:
- WeatherController:一个类,处理从视图发来的请求,调用模型获取数据,然后更新视图。
public class WeatherController {private WeatherRepository repository;private WeatherView view;private String city;public WeatherController(WeatherView view, String city) {this.view = view;this.city = city;repository = new WeatherRepository();}public void updateWeather() {WeatherModel weather = repository.getWeather(city);view.showWeather(weather);}
}interface WeatherView {void showWeather(WeatherModel weather);
}
在这个例子中,WeatherActivity
扮演了 WeatherView
的角色,它实现了 showWeather
方法来更新UI。当用户打开应用时,WeatherActivity
创建 WeatherController
实例并请求更新天气信息。WeatherController
调用 WeatherRepository
获取数据,然后通过 WeatherActivity
更新UI。
这个简单的例子展示了MVC模式如何将应用程序的输入、处理和输出分开,以提高代码的组织性和可维护性。
示例2:MVP
继续使用天气应用的例子,但这次我们将采用MVP(Model-View-Presenter)模式。在MVP模式中,视图(View)不再直接与模型(Model)交互,而是通过呈现器(Presenter)来完成。这样可以进一步解耦视图和模型,使得视图只负责显示,模型只负责数据和业务逻辑,而所有界面逻辑都放在呈现器中处理。
2.1 Model(模型)
模型部分与MVC模式相似,负责处理数据和业务逻辑。
public class WeatherRepository {public WeatherModel getWeather(String city) {// 调用网络API获取天气数据,并返回一个WeatherModel对象// 为了简化,我们假设直接返回一个WeatherModel实例return new WeatherModel("晴", 25, 30, "北风3级");}
}public class WeatherModel {private String condition;private int temperature;private int humidity;private String wind;// 构造函数、getter和setter省略
}
2.2 View(视图)
在MVP中,视图不再包含任何业务逻辑,只负责显示数据和传递用户操作。
public interface WeatherView {void showWeather(WeatherModel weather);void showLoading();void hideLoading();
}
public class WeatherActivity extends AppCompatActivity implements WeatherView {private WeatherPresenter presenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_weather);WeatherRepository repository = new WeatherRepository();presenter = new WeatherPresenter(this, repository);presenter.onViewCreated();}@Overridepublic void showWeather(WeatherModel weather) {// 更新UI,显示天气信息TextView cityNameView = findViewById(R.id.cityName);cityNameView.setText("北京");TextView weatherConditionView = findViewById(R.id.weatherCondition);weatherConditionView.setText(weather.getCondition());TextView temperatureView = findViewById(R.id.temperature);temperatureView.setText(String.valueOf(weather.getTemperature()));}@Overridepublic void showLoading() {// 显示加载指示器}@Overridepublic void hideLoading() {// 隐藏加载指示器}
}
2.3 Presenter(呈现器)
呈现器负责接收视图的意图,处理业务逻辑,并更新视图。
public class WeatherPresenter {private WeatherView view;private WeatherRepository repository;public WeatherPresenter(WeatherView view, WeatherRepository repository) {this.view = view;this.repository = repository;}public void onViewCreated() {view.showLoading();fetchWeather();}private void fetchWeather() {WeatherModel weather = repository.getWeather("北京");view.hideLoading();view.showWeather(weather);}
}
在这个MVP模式的例子中,WeatherActivity
实现了 WeatherView
接口,它只负责显示数据和传递用户操作。所有的业务逻辑,如获取天气数据,都由 WeatherPresenter
处理。当 WeatherActivity
创建时,它会创建 WeatherPresenter
实例,并在视图创建后调用 onViewCreated
方法。WeatherPresenter
则通过 WeatherRepository
获取天气数据,并通过 WeatherView
接口更新视图。
这种模式的优点是视图和模型完全解耦,视图不依赖于模型,而是依赖于呈现器。这使得单元测试变得更容易,因为你可以轻松地模拟视图和呈现器。同时,这也使得视图的代码更加简洁,因为所有的业务逻辑都被移到了呈现器中。
示例3:MVVM
在MVVM(Model-View-ViewModel)模式中,ViewModel充当了View和Model之间的桥梁。ViewModel负责处理所有的业务逻辑和数据,而View则负责显示数据和收集用户的输入。ViewModel通知View数据的变化,通常是通过数据绑定来实现的。
让我们继续使用天气应用的例子来说明MVVM模式:
Model(模型)
模型部分负责定义数据结构和业务逻辑。
public class WeatherModel {private String condition;private int temperature;private int humidity;private String wind;// 构造函数、getter和setter省略
}
View(视图)
在MVVM中,视图通常使用数据绑定来简化ViewModel和View之间的通信。
<!-- activity_weather.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="weatherViewModel"type="com.example.weatherapp.WeatherViewModel" /></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{weatherViewModel.weatherModel.condition}"android:textSize="24sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{weatherViewModel.weatherModel.temperature}"android:textSize="18sp" /><!-- 其他界面元素 --></LinearLayout>
</layout>
public class WeatherActivity extends AppCompatActivity {private WeatherViewModel weatherViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_weather);weatherViewModel = new ViewModelProvider(this).get(WeatherViewModel.class);weatherViewModel.getWeather("北京");}
}
ViewModel(视图模型)
ViewModel负责业务逻辑和数据获取,并通过LiveData或ObservableField更新UI。
public class WeatherViewModel extends ViewModel {private WeatherRepository repository;private MutableLiveData<WeatherModel> weatherModel;public WeatherViewModel() {repository = new WeatherRepository();weatherModel = new MutableLiveData<>();}public LiveData<WeatherModel> getWeatherModel() {return weatherModel;}public void getWeather(String city) {weatherModel.setValue(repository.getWeather(city));}
}
在这个MVVM模式的例子中,WeatherViewModel
负责从 WeatherRepository
获取天气数据,并通过 LiveData
将数据暴露给View。WeatherActivity
使用数据绑定来观察 LiveData
中的数据变化,并更新UI。
当 WeatherActivity
创建时,它会获取 WeatherViewModel
的实例,并请求天气数据。WeatherViewModel
通过 WeatherRepository
获取数据,并通过 LiveData
将数据更新到View中。当数据发生变化时,LiveData
会自动通知View进行更新。
这种模式的优点是View和Model之间的耦合度更低,ViewModel可以独立于View进行单元测试。同时,由于使用了数据绑定,View的代码更加简洁,ViewModel负责所有的数据管理和UI更新逻辑。