摘要
公司需要对已上线的APP进行组织架构的调整,看着一个类里面1000+甚至2000+的代码,有种摸不着头脑的感觉。对设计模式一窍不通的我,这两天在学习如何能够有效分离同一个类的代码量,于是看了MVC/MVP/MVVM的设计模式,在此之前只懂得一点点MVC设计模式,但没法解决Activity或Fragment类代码臃肿的问题,然后看了MVP和MVVM的设计思路,MVP是最适合重构当前已上线APP的设计模式。
一.什么是MVP?
百度搜索MVP设计模式,找到很多MVP文字介绍的文章,看了那么多篇的文章,文字怎么描述MVP的定义TeachCourse的确记不住了,唯一还有印象的是描述MVP的Demo,开发的步骤:
1、建立bean
- public class UserBean {
- private String mFirstName;
- private String mLastName;
- public UserBean(String firstName, String lastName) {
- this. mFirstName = firstName;
- this. mLastName = lastName;
- }
- public String getFirstName() {
- return mFirstName;
- }
- public String getLastName() {
- return mLastName;
- }
- }
2、建立model接口(处理业务逻辑,这里指数据读写)
- public interface IUserModel {
- void setID(int id);
- void setFirstName(String firstName);
- void setLastName(String lastName);
- int getID();
- UserBean load(int id);// 通过id读取user信息,返回一个UserBean
- }
3、建立view接口(更新ui中的view状态),这里列出需要操作当前view的方法
- public interface IUserView {
- int getID();
- String getFristName();
- String getLastName();
- void setFirstName(String firstName);
- void setLastName(String lastName);
- }
4、建立presenter(主导器,通过iView和iModel接口操作model和view),activity可以把所有逻辑给presenter处理,这样java逻辑就从手机的activity中分离出来
- public class UserPresenter {
- private IUserView mUserView;
- private IUserModel mUserModel;
- public UserPresenter(IUserView view) {
- mUserView = view;
- mUserModel = new UserModel();
- }
- public void saveUser( int id, String firstName, String lastName) {
- mUserModel.setID(id);
- mUserModel.setFirstName(firstName);
- mUserModel.setLastName(lastName);
- }
- public void loadUser( int id) {
- UserBean user = mUserModel.load(id);
- mUserView.setFirstName(user.getFirstName()); // 通过调用IUserView的方法来更新显示
- mUserView.setLastName(user.getLastName());
- }
- }
5、UserActivity实现了IUserView及View.OnClickListener接口,同时有一个UserPresenter成员变量:
- public class UserActivity extends Activity implements OnClickListener ,
- IUserView {
- private EditText mFirstNameEditText , mLastNameEditText , mIdEditText ;
- private Button mSaveButton , mLoadButton ;
- private UserPresenter mUserPresenter ;
- ...
- }
重写了OnClick方法:
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch ( v. getId()) {
- case R .id .saveButton :
- mUserPresenter .saveUser (getID (), getFristName (),
- getLastName ());
- break ;
- case R .id .loadButton :
- mUserPresenter .loadUser (getID ());
- break ;
- default :
- break ;
- }
- }
这属于MVP设计模式其中的一个Demo,因为不止在一篇文章里看到,自然对它的实现思路了解清楚,MVP属于MVC模式的升级版,即Module,View,Presenter,在一个完整的MVP例子中划分成四个部分:Bean,Module(IModule,IModuleImpl),Presenter(IPresenter,IPresenterImpl),View(Activity或Fragment),是否了解接口的使用和定义方法决定你是否理解四大部分的意义,如果未阅读过《你会错过的接口理解三部曲:定义,设置和实现》这篇文章的童鞋,建议先熟悉一下接口的使用或者点击“搜索”按钮,输入“接口”查找,阅读更多相关文章。
PS:学习一种设计模式,对于新手来说先了解设计模式的实现过程,比你直接阅读概念文字容易理解一点,然后根据实现的思路结合到Project Develop中,是快速掌握知识的一种方式,下面由浅入深说明怎么在Android Project中使用MVP。在一个设计模式使用过程根据项目的具体情况,会有所区别,比如:上面的Demo,可能在代码量很多的时候,会分别多创建IUserModelImpl实现类、IUserPresenter接口,然后在实现类中完成功能的封装,通过IUserView接口在Activity或Fragment类中处理结果,思路就是将一个类的代码分离,有一种各司其职的感觉,最后将结果反馈给boss,让boss做最后的决策。
二.MVP开发百度地图Demo(AS开发工具)
使用百度地图,第一步使用百度账号申请百度地图密钥,第二步下载百度地图jar包添加到libs文件夹中,第三步配置build.gradle文件,在build.gradle文件的android标签内指定jniLibs的路径
- sourceSets {
- main {
- jniLibs.srcDir 'libs'
- }
- }
否则报错,java.lang.UnsatifiedLinkError:Native method not found:com.baidu.platform.comjni.map.commonmemcache.JNICommonMemCache.Create,也可以将libs存放so包的文件夹(arm64-v8a/armeabi/armeabi-v7a/x86/x86_64)放置在src/main/jniLibs文件夹内,这时候不需要配置build.gradle指定jniLibs的路径。
实现的功能,在百度地图动态加载图层,需要用到的数据是各个图层的经纬度信息,实现的思路:
1、IRecycleModule和IRecycleModuleImpl生成经纬度数据信息
- /**
- * Created by postmaster@teachcourse.cn on 2016/9/9.
- */
- public class IRecycleModuleImpl implements IRecycleModule {
- @Override
- public List<LatLng> getLatLng() {
- List<LatLng> list = new ArrayList<LatLng>();
- list.add(dealLatLng(113.277521,23.12155));
- list.add(dealLatLng(113.276614,23.124774));
- list.add(dealLatLng(113.27612,23.123087));
- list.add(dealLatLng(113.277638,23.123436));
- list.add(dealLatLng(113.277188,23.121658));
- return list;
- }
- /**
- * 经度值大于纬度,注意构造方法:LatLng(double latitude,double longitude)
- * @param longitude
- * @param latitude
- * @return
- */
- private LatLng dealLatLng(double longitude,double latitude){
- return new LatLng(latitude,longitude);
- }
- }
2、IRecycleView在百度地图显示图层内容
- /**
- * Created by postmaster@teachcourse.cn on 2016/9/9.
- */
- public interface IRecycleView {
- void displayIcon(OverlayOptions overlayOptions);
- }
在IRecyclePresent的IRecyclePresenterImpl实现方法中调用:
- mIRecycleView.displayIcon(ooA);
在MainActivity中实现:
- @Override
- public void displayIcon(OverlayOptions overlayOptions) {
- mMap.addOverlay(overlayOptions);
- }
3、IRecyclePresenter和IRecyclePresenterImplements生成百度图层
- /**
- * Created by postmaster@teachcourse.cn on 2016/9/9.
- */
- public class IRecyclePresenterImpl implements IRecyclePresenter {
- private IRecycleView mIRecycleView;
- private Context mContext;
- public IRecyclePresenterImpl(IRecycleView mIRecycleView, Context mContext) {
- this.mIRecycleView = mIRecycleView;
- this.mContext = mContext;
- }
- @Override
- public void dynamicProductIcon() {
- final View markView = LayoutInflater.from(mContext).inflate(
- R.layout.bad_things_bg, null);
- ImageView img = (ImageView) markView.findViewById(R.id.marker_view_bg);
- Bitmap map = BitmapFactory.decodeResource(mContext
- .getResources(), R.drawable.icon_marka_bad);
- img.setImageBitmap(map);
- BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory
- .fromView(markView);
- IRecycleModule module=new IRecycleModuleImpl();
- for (LatLng latLng:module.getLatLng()){
- OverlayOptions ooA = new MarkerOptions().position(latLng).icon(bitmapDescriptor);
- mIRecycleView.displayIcon(ooA);
- }
- }
- }
PS:在百度地图显示图标的时候,需要注意LatLng这个类,该类构造方法传入的参数,前者是纬度,后者是经度,百度拾取坐标系统获取的数值:经度,纬度,所以定义了dealLatLng()方法处理,否则地图显示空白。
设计的过程,通常是变化的,在百度地图添加图标的例子中,详细划分MVP设计模式为接口和实现类,可能在有的时候直接定义接口,具体实现放在IRecyclePresenterImpl类实现IRecycleModule,现在独立出来一个IRecycleModuleImpl;同时记住一个原则,Activity或Fragment负责更新View视图,Presenter负责处理逻辑,IRecycleView负责反馈Presenter处理结果给Activity或Fragment,IRecycleModule负责操作数据内容。按照MVP这样的设计模式,你会发现Activity或Fragment类的代码量有效分离,是不是很爽。
推荐阅读:
你可能感兴趣的文章
转载请注明出处: https://www.teachcourse.cn/2034.html ,谢谢支持!