Recientemente quería refactorizar el código, porque el proyecto necesita ser utilizado por varias escuelas, y la interfaz de cada escuela es diferente, pero las funciones son casi idénticas. Aunque usando ramas de Gradle se pueden lograr diferencias en el código, la lógica del código de la parte común también es cada vez mayor, así que quería refactorizarlo. He estado mirando el patrón MVP, que está bastante de moda recientemente, y me pareció muy adecuado. Sin embargo, muchos materiales en Internet están copiados unos de otros, y algunos incluso tienen errores. Quería describir el patrón MVP según mi propio entendimiento para facilitar la comprensión de los demás. Primero hablemos del patrón de diseño MVC, que es el más familiar para todos.

El patrón MVC desacopla la capa M y la capa V; la capa M y la capa V interactúan a través de la capa C.
Luego echemos un vistazo a MVP. En mi texto a continuación, las palabras que comienzan con I significan interfaz (es agotador dibujar el diagrama a mano...).
La mayor diferencia entre MVP y MVC es que la capa P reemplaza a la antigua capa C; lo que se controla ya no es la implementación concreta, sino las interfaces. De esta manera, ya sea el desarrollo en equipo o los cambios frecuentes de UI, no afectarán a la capa P. Siempre que las interfaces de las capas C y V no cambien, las modificaciones de la UI solo requieren cambiar la implementación de la capa V, y ni siquiera la implementación de la capa C necesita cambiar. Así el código es muy claro y fácil de probar, porque la capa de lógica y la capa de vista están completamente separadas. A continuación, hablemos con código. Primero veamos el patrón MVC, usando el ejemplo del inicio de sesión. Android ya ha separado muy bien la capa C y la capa V: nuestro XML equivale a la capa V, y Activity equivale a la capa C.
public interface ICallback{
void receive(boolean success);
}
public class LoginModel{
public void login(String name,String password,ICallback callback){
WebApi.login(name,password,callback);
}
}
public class LoginActivity extends Activity{
private LoginModel mLoginModel;
private EditText mUserNameEt;
private EditText mPasswordEt;
private Button mSubmitBtn;
public void onCreate(......){
mLoginModel = new LoginModel(...);
mSubmitBtn.setOnClickListener(new OnClickListener(View view){
mLoginModel.login(mUserNameEt.get...,mPasswordEt.get...,new ICallback(){
public void receive(boolean success){
if(success){
startActivity(new Intent(this,MainActivity.class));
finish();
} else {
Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
}
}
});
});
}
}
Veamos ahora cómo se escribe con el patrón MVP. En los comentarios debajo del artículo, un colega sugirió escribir una clase de contrato. Lo investigué y escribir una clase de contrato es más conveniente, así que el siguiente código es el que modifiqué.
public interface ILoginContract {
public interface ILoginModel{
public void login(String name,String password,ICallback callback);
}
public interface ILoginPresenter{
public void login(String name,String password);
}
public interface ILoginView{
public void showDialog();
public void dismissDialog();
public void showToast(String message);
public void navigateToMain();
}
}
public class PresenterImpl implements ILoginPresenter,ICallback{
private ILoginView mLoginView;
private ILoginModel mLoginModel;
public PresenterImpl(ILoginView loginView){
this.mLoginView = loginView;
this.mLoginModel = new LoginModelImpl();
}
public void login(String name,String password){
if(isEmpty(name)||isEmpty(password)){
this.mLoginView.showToast("用户名或密码不能为空");
return;
}
this.mLoginModel.login(name,password,this);
}
public void receive(boolean success){
if(success){
this.mLoginView.navigateToMain();
}else{
this.mLoginView.showToast("登录失败");
}
}
private boolean isEmpty(String text){
return text==null||"".equals(text)?true:false;
}
}
public class LoginActivity extends Activity implements ILoginView{
private IPresenter mPresenter;
private EditText mUserNameEt;
private EditText mPasswordEt;
private Button mSubmitBtn;
public void onCreate(......){
mPresenter = new PresenterImpl(this);
mSubmitBtn.setOnClickListener(new OnClickListener(View view){
mPresenter.login(mUserNameEt.getText().toString(),
mPasswordEt.getText().toString());
});
}
public void showDialog(){
//显示一个转圈的dialog;
}
public void dismissDialog(){
//隐藏转圈的dialog;
}
public void showToast(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
public void navigateToMain(){
startActivity(new Intent(this,MainActivity.class));
finish();
}
}
Las clases y el código de MVP son ciertamente más abundantes, pero valen mucho la pena. Se puede ver que la lógica del código ahora es más clara que escribiéndola con el patrón MVC, las pruebas de código también son más simples, e incluso se pueden completar las funcionalidades cuando solo se tienen las funciones sin los diseños de página. Los cambios de UI tampoco afectarán ningún código de negocio.
El patrón de diseño MVP anterior es mi comprensión personal. Si hay algún error, por favor corríjanme. Gracias. Discutamos juntos y progresemos juntos.
Autor del artículo: o动感超人o