android基础复习笔记——25.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里的c从activity里面抽出来,抽出来的那一部分叫p,而mvp里面,activity里面只留下了v那一部分。

mvp之所以比mvc更有优势,并不是mvp的思想本身,而是mvp代码的实现方式,从代码的结构上把presenter和view拆开了,mvc是vc两个有耦合,而mvp从代码上,物理上,把v和p给拆开了,这是他们的主要区别。本质上他们的三层结构是差不多的。
有一种说法,mvp因为切断了v和m之间的链接,让代码更加松散了,因此更有优势。但是,我们平时写代码也没有把m和v连接(mvc变种)。所以这种说法是站不住脚的。

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);
    }
}

5.mvvm

mvvm大致就是一个双向绑定的mvp。

程序里面有三种数据,数据库数据(包括网络数据),内存数据(也就是java里的变量),表现数据(界面展示的数据)。双向绑定就是内存数据和表现数据实时地互相更新。
让mvp不用showData绑定数据,让他们load的时候就双向绑定,就是mvvm。

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(){

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值