Web的架构经过量年的发展已非常成熟了,我们经常使用的SSM,SSH等等,架构都非常标准。个人认为,Web服务逻辑比较清晰,目的明确,流程也相对固定,从服务器收到要求开始,经过1系列的的拦截器,过滤器->被转发到控制器手中->控制器再调用服务->服务再调用DAO获得想要的数据->最后把数据返回给web层。哪怕中间增加1些东西,如缓存甚么的。他的模型仍然是以用户要求的线程为生命周期,经过1个个切面(层)的结构,感觉类似于流水线的结构吧。
而Android App则有所不同,他没有像用户要求这样1个统1的动身点,最接近的多是来自于UI的事件,但是远不单单于此。根据app不同的需求,其结构也会千差万别,所以很难有较为统1的架构。
但是客户端类app确切是较为常见的App类型,其结构还是有迹可循的。
1.MVC
mvc现在是用的人最多,同时也是Android官方的设计模式,可以说Android App本来就是MVC的,View对应布局文件xml,Controller对应Activity,Model对应数据模型。
这类App1般会定义1个BaseActivity,BaseActivity内部实现了网络的异步要求,本地数据的存储加,数据库访问载等复用性较强的逻辑。逻辑控制则在对应的Activity中实现。
MVC的缺点:Activity过于臃肿,常常1个Activity几百上千行代码。View层的XML控制力其实非常弱,众多的View处理还是要放在Activity进行,这样的话,Activity就既包括了View又包括了Controller,耦合高,不利于测试扩大,可读性也变差。
2.MVVM
用过VS开发过.net的人肯定知道MVVM的强大的地方,仅需要点点鼠标,数据库里的信息和View的控件显示就被简单的绑定了。
而Android的数据绑定个人认为还是不够成熟的,用法长这样android:text=”@{user.username}”/>
在xml里面配置数据模型。1是控制力不够,2是部份逻辑需要放到数据Model里处理。
3.MVP
最近在Android上利用比较火的模式。相较于MVC,MVP将Activity中的业务逻辑抽取出来,将Activity,Fragment等作为View层,专职与界面交互。而Presenter则负责数据Model的填充和View层的显示。View不直接与Model交互,解耦了Actiity。
这样可以做到逻辑和界面交互的完全分离,方便测试,界面升级等。代码的可读性也大大增加。
对我自己,在我自己架构项目的时候确切遇到了1些困难,也有选择障碍,经过1番思考。我有了自己的见解,整体还是偏向于MVP,但又有些不同。多是MVP+MVVM(伪)吧。
首先是包结构
1.View层
view层依照Android组件的分类,可使用接口通讯,也能够使用类似EventBus的事件框架进行通讯
Action包就是事件实体,这里使用的是我自己实现的事件框架。
2.Model层
model层包括数据模型,实体类,和dao,http等数据获得得代码。回掉的话可使用接口,也能够使用事件框架。另外缓存也放在这里。
3.Presenter
包括Base(自己实现的Presenter框架,其实就是将Activity抽取了1层),Service包是Android组件Service
Impl是业务的实现,下面1堆I开头的是业务接口。
这里讲1下Base,Base相当于控制器,拿登陆来举例,1个登陆操作可能触及多个界面,多个业务逻辑单元。比如登陆,首先是要求网络的逻辑,除此以外,登陆成功后,需要对会话,用户基础信息等进行持久化;还有控制器需要控制各个界面的刷新。这些都是在控制器Base中完成的,他是1组逻辑的控制单元,负责1个典型的业务,比如说登陆。
下面的重点是业务接口,例如登陆ILogin,如果自己实现,你需要写1大堆的东西,网络要求,异步处理,Handler,异常处理,JSON解析,显示,洋洋洒洒最少上百行了。如果你的项目需要快速上线怎样办?同时你又想保持项目的逻辑结构,以后做更细致的改进,这时候候就体现了接口的重要性。这里安利我1个比较快速的实现链接也是我实现的1个小框架。
用起来画风是这样的。
public class LoginPresenter extends Presenter implements ActivityOnCreatedListener,ICallBack<User,Throwable>{
private ILogin ILogin;
@Override
protected void onContextChanged(ContextChangeEvent event) {
}
@Override
public void OnPresentInited(Context context) {
ILogin = HttpProxyFactory.With(ILogin.class).setCallBack(this).setViewContent(getActivityRaw()).establish();
getActivityInter().setOnCreateListener(this);
}
@Override
public void ActivityOnCreated(Bundle savedInstanceState, final Activity activity) {
getActivityInter().getView(R.id.btn_login)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LoginActivity ac = (LoginActivity) activity;
ac.progressDialog.show();
getActivityInter().getView(R.id.btn_login).setClickable(false);
EditText name = getActivityInter().getView(R.id.login_name);
EditText pass = getActivityInter().getView(R.id.login_pass);
ILogin.login(name.getText().toString(),pass.getText().toString());
}
});
}
@Override
public void onSuccess(User user) {
Log.e("gy",user.toString());
getActivityRaw().finish();
navTo(HomeActivity.class);
}
@Override
public void onFailed(Throwable throwable) {
ILoginCallBack callBack = (ILoginCallBack) getContext();
callBack.onLogFailed(throwable.getMessage());
}
}
你可以发现ILogin = HttpProxyFactory.With(ILogin.class).setCallBack(this).setViewContent(getActivityRaw()).establish();
这么简单,你的ILogin业务接口就被框架实现了,简单的说就是用了动态代理,框架根据你在接口上绑定的注解信息,帮你动态代理处1个业务实现对象。帮你包办了网络要求,异步处理,异步回掉,异常处理,JSON解析,显示等1大堆操作。
如何绑定你的需求?
ILogin接口张这样的
public interface ILogin {
@HttpSrcMethod(url = "/store/login",session = Global.SKEY_UNLOGIN,filters = ResultFilter.class)
public User login(@Param("tel")String name,@Param("password")String passwd);
}
返回值模型Model User比较简单,我们换1个比较典型的
@JsonOrm
public class ResultArea implements IHandler{
@JsonString("name")
private String name;
@JsonString("id")
private String id;
@BindListView(CityPickerActivity.ListViewId)
@JsonSet(name = "areas",clazz = Area.class)
private List<Area> child;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Area> getChild() {
return child;
}
public void setChild(List<Area> child) {
this.child = child;
}
@Override
public void handler() throws Exception {
if (child == null)
child = new ArrayList<>();
child.add(0,new Area(name,id));
}
}
注解几近映照了你所有的业务接口协议,包括要求参数,URL,头,返回值的json映照,对应View层的视图显示等等。
使用这类临时解决方案以后,后期如有需求,自己再选用其它框架,或自己实现业务接口便可,根本不需要动其他模块,从而保证了可扩大性。
上一篇 仿映客送礼特效