android基础—Android常见项目架构示例mvc、mvp、mvvm
对于移动端来说他的架构都非常简单,系统性的架构设计一般是用于大型项目,比如web服务,做网站的,他们一般都需要系统性的架构设计,因为一做就是很大的东西,好几十人一起做。而对移动端,一般来说,简单架构就足够了,除非软件非常大,比如淘宝,淘宝超级大,还有其他国内一些大团队做的应用,这些东西太大了,我需要系统性地去设计一些架构,才能够hole住他,才能让他做得很大的时候不会散不会乱,不会跑不动,架构这东西,所有软件都会有,不是你需不需要,他是一定会有的。哪怕一开始没有,你做着做着就有了。不够你做着做着再去想他,你改的时候会比较累。就是移动端的架构通常来说都是非常简单的。虽然移动端的架构很简单,但是对于mvc、mvp、mvvm,对他们的误解是很大的。
1.架构有什么用?
对于web项目来说,他们的架构虽然大,但是架构设计并没有很难,是因为有很多成熟的框架可以用,不管你是用php还是node、java都是有很多成熟的框架的,不过有成熟框架就是因为这个东西很复杂,所以有些成熟框架大家做出来都用,有很多人尝试,有很多人认可,最终剩下几个活着的很好。这个框架本身就提供了项目的架构了,这些框架提供的架构,框架就是framework,就是你把她这一套东西拿过来,按他的公式去套进去用,这是框架。而架构是你项目的结构,比如你什么东西放在哪个目录,然后你代码哪个东西写在哪个方法里面,什么东西写在哪个类里面,这是你的架构。框架是他给你套的一个束缚,一个约束,然后你写起来也比较轻松。也就是说你通过使用框架的方式,就把项目的架构搭建好了,你也用这个框架,我也用这个框架,那么我们的架构是一样的。这个是对于很多大项目来说,尤其是传统的web项目来说,他们一般是这样的,而对于android开发来说,不一样,android SDK 他提供的方案就可以写出完整的软件了,我们不需要去遵守各种东西,因为对于一些web项目来说,你不用框架行不行?能行,但是对于他们来说,他们用什么写?他们用语言写,比如我用php来写,我用java来写,我用js来写,或者我用node来写。而对于android开发,我们是用android SDK 来写,我们不会说我们用java写一个android项目。其实他们也是这样的,他们如果只用他们语言本身,去搭一个网站,行不行?能行,但是太麻烦了。android强制我们用他的SDK,才能做软件开发,但是他强制的同时,也对我们制定出各种各样的规则,比如我们只能在activity里面去写界面,然后图标必须在什么地方去设置,通过这些规则去限制,我 们已经能用比较稳定的代码来写软件了,你写也稳定,我写也稳定,学个三天就能上手,写个软件运行起来不会奔溃,只要你写的软件足够简单,都不会奔溃,因为我们只有这一种方法写。这个是android SDK 对我们提供的限制,同时也让我们写起来会比较稳定。
然后,由于移动端的软件功能是相对简单的,所以写简单软件你也不需要再加额外架构,但是如果是商业项目,你没有架构,那会有什么坏处呢?
1.不同的人风格不同,一个人写的代码结构换个人可能会看不懂。咱都*写,我写的代码你可能看不懂。每个团队也有自己的风格和规范,来了一个新人的时候,他看懂团队代码可能会有门槛
2.项目越做越大的时候可能会面临改不动的问题,软件结构不好调整。项目做得越大,这种风险就会越大。
2.mvc、mvp、mvvm的主流理解
3.mvc
class View {
//相当于xml
//用来显示以及把用户事件传给controller
Controller controller;
void showData(int data) {
//...
}
void clicked() {
controller.viewClicked(this);
}
}
class Controller {
//相当于activity
//用来调度,去操作model,让他去执行业务逻辑,他告诉model你要做什么?model再具体去实现。
Model model;
void viewClicked(View view) {
switch (view.getId()) {
case R.id.bt:
model.dataAdd(1);
break;
}
}
}
class Model {
//相当于相关数据操作类
//将实现结果给view,让view去更新
int data;
View view;
public void dataAdd(int delta) {
data += delta;
view.showData(data);
}
}
这种开发结构有一种缺陷,controller和view结合太紧密了,activity会一行一行操作view,我是把结果交给view去做,但是我对view的干涉也太多了,我并不是告诉他数据是这个你去显示吧。而是把每一行告诉他你要怎么做,你的这个控件要这么显示。这样写,你的的逻辑比较复杂的时候,controller和view就缠在一起了。你的view的显示内容的改变总要c去做具体操作。而不是让view去做具体操作。
4.mvp
mvp之所以比mvc更有优势,并不是mvp的思想本身,而是mvp代码的是实现,从代码的结构上把presenter和view拆开了,mvc是透明两个有耦合,而mvp从代码上,物理上,把v和p给拆开了,这是他们的主要区别。本质上他们的三层结构是差不多的。
有一种说法,mvp因为切断了v和m之间的链接,让代码更加松散了,因此更有优势。但是,我们平时写代码也没有把m和v连接(mvc变种)。所以这种说法是站不住脚的。
还有一种说法,mvp通过把p单独抽出来,强行隔离了v和p,由于mvp具有这个特性,所以跟mvc不一样了。因为mvc最大劣势就是c和v都在activity里面。他们的关系他紧密了。这种说法对不对等会讨论。
主流的mvp就是把mvc里的c从activity里面抽出来,抽出来的那一部分叫p,而mvp里面,activity里面只留下了v那一部分。
m:
public class DataCenter {
public static String[] getData() {
return new String[]{"1","2"};
}
public static void setData(){
}
}
v:
public class MvpActivity extends AppCompatActivity implements Presenter.IView {
private EditText et1;
private EditText et2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
new Presenter(this).load();
}
@Override
public void showData(String data1, String data2) {
et1.setText(data1);
et2.setText(data2);
}
}
p:
public class Presenter {
IView iView;
Presenter(IView iView){
this.iView = iView;
}
void load(){
String[] data = DataCenter.getData();
iView.showData(data[0],data[1]);
}
interface IView{
void showData(String data1,String data2);
}
}
也可以把v从activity里面拆出来,保留c,就自定义view继承LinerLayout,然后把view的功能转移到自定义view里面。然后p可以写在activity里面,控制的接口让自定义去实现。(这种应该没什么人用吧,用来演示mvc也可以把m和v拆开,用c来控制)
5.mvvm
程序里面有三种数据,数据库数据(包括网络数据),内存数据(也就是java里的变量),表现数据(界面展示的数据)。双向绑定就是内存数据和表现数据实时地互相更新。
让mvp不用setdata绑定数据,让他们load的时候就双向绑定,就是mvvm。mvvm大致就是一个双向绑定的mvp。
public class MvvmActivity extends AppCompatActivity {
private EditText et1;
private EditText et2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
new ViewModel(new ViewBinder(),et1,et2).load();
}
}
public class ViewBinder {
void bind(EditText editText, final ViewModel.TextAttr text) {
//怎么绑定,监听器,但是text怎么监听呢?包起来,在ViewModel里面
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (!s.equals(text.getText())) {
text.setText(s.toString());
}
}
});
text.setOnChangeListener(new ViewModel.TextAttr.OnChangeListener() {
@Override
public void onChange(String newTexr) {
if (!newTexr.equals(editText.getText().toString())) {
editText.setText(newTexr);
}
System.out.println("被动改变:"+newTexr);
}
});
}
}
public class ViewModel {
TextAttr data1 = new TextAttr();
TextAttr data2 = new TextAttr();
ViewModel(ViewBinder binder, EditText et1,EditText et2){
binder.bind(et1,data1);
binder.bind(et2,data2);
}
void load() {
String[] data = DataCenter.getData();
data1.setText(data[0]);
data2.setText(data[1]);
}
static class TextAttr {
private String text;
private OnChangeListener listener;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
if (listener != null) {
listener.onChange(text);
}
}
void setOnChangeListener(OnChangeListener listener){
this.listener = listener;
}
interface OnChangeListener {
void onChange(String newTexr);
}
}
}
public class DataCenter {
public static String[] getData() {
return new String[]{"1","2"};
}
public static void setData(){
}
}
本文地址:https://blog.csdn.net/qq_36333289/article/details/110239460
上一篇: axios二次封装