Récemment, j'ai voulu refactoriser le code parce que le projet doit être utilisé par plusieurs écoles, et l'interface utilisateur de chaque école est différente, mais les fonctionnalités sont presque identiques. Bien que l'utilisation de branches Gradle puisse gérer les différences de code, la logique de code dans les parties communes ne cesse de croître, j'ai donc voulu refactoriser. J'ai jeté un œil au modèle MVP récemment populaire et je l'ai trouvé très adapté. Cependant, une grande partie du contenu en ligne est simplement recopiée, et certaines parties contiennent même des erreurs, j'ai donc voulu décrire le modèle MVP selon ma propre compréhension pour faciliter la compréhension des autres. Tout d'abord, parlons du modèle de conception MVC que tout le monde connaît le mieux.

Le modèle MVC découple la couche M et la couche V ; la couche M et la couche V interagissent via la couche C.
Voyons maintenant le MVP. Dans mon texte ci-dessous, les noms commençant par I désignent des interfaces (dessiner le diagramme à la main est fatigant...)
La plus grande différence entre MVP et MVC est que la couche P remplace l’ancienne couche C et ne contrôle plus des implémentations spécifiques, mais des interfaces. Ainsi, ni le développement à plusieurs développeurs ni les changements fréquents d’interface utilisateur n’affecteront la couche P. Tant que les interfaces des couches C et V restent inchangées, les changements d’interface utilisateur nécessitent uniquement de modifier l’implémentation de la couche V ; l’implémentation de la couche C n’a même pas besoin d’être modifiée. Cela garde le code très clair et facilite les tests, car la couche logique et la couche vue sont complètement séparées. Laissez-moi m’exprimer avec du code—en commençant par le modèle MVC, avec la connexion comme exemple. Android sépare déjà bien la couche C et la couche V : le XML que nous écrivons équivaut à la couche V, et l’Activity équivaut à la couche 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();
}
}
});
});
}
}
Voyons comment l’écrire avec le modèle MVP. Un commentaire sous l’article mentionnait l’écriture d’une classe de contrat. Je me suis renseigné, et écrire une classe de contrat est effectivement plus pratique, donc le code ci-dessous est celui que j’ai révisé.
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();
}
}
Le modèle MVP exige effectivement plus de classes et de code, mais cela vaut vraiment la peine. Vous pouvez voir que la logique du code est plus claire à écrire que dans le modèle MVC, et que les tests du code sont aussi plus simples. Vous pouvez même réaliser des fonctionnalités lorsque vous n’avez que la fonctionnalité et aucune maquette d’interface utilisateur, et les changements d’interface utilisateur n’affecteront aucun code métier.
Le modèle de conception MVP ci-dessus est ma compréhension personnelle. S’il y a des erreurs, veuillez me corriger. Merci. Discutons et améliorons ensemble.
Soumis par : oDynamicSupermano