Android与设计模式(4)外观/桥接/MVP

详细代码请见https://github.com/zackLangChina/DesignPatternLearning

Android与设计模式(1)
单例模式 ** 工厂模式 ** 策略模式 ** 命令模式
Android与设计模式(2)
观察者模式 ** 备忘录模式 ** 模板方法模式 ** 中介者模式
Android与设计模式(3)
代理模式 ** 适配器模式 ** 装饰模式 ** 享元模式
Android与设计模式(4)
外观模式 ** 桥接模式 ** MVP模式

13,外观模式

Android与设计模式(4)外观/桥接/MVP_第1张图片
外观模式

使用场景:

隐藏一系列小系统组成的大系统的复杂性,并向客户端提供了一个客户端可以访问这些系统的接口。客户端不与系统耦合,外观类与系统耦合。

Android中的应用:

Context提供的sendBroadcast、startActivity、bindService等方法,把内部复杂的实现隐藏了起来。
另外,我觉得JNI也是一个外观模式,java层的JNI类把native的处理隐藏了起来,使得java层其他代码可以像调用java代码一样使用native的功能。

组成部分

系统 | 外观类

代码示例:

//外观接口
interface Person {
    void talk();
    void hear();
    void smell();
}
//外观类,将三个子系统(嘴耳鼻)整合,并提供对外的接口
class LiSi implements Person {
    private Mouth mMouth;
    private Ear mEar;
    private Nose mNose;

    public LiSi() {
        mMouth = new Mouth();
        mEar = new Ear();
        mNose = new Nose();
    }

    @Override
    public void talk() {
        mMouth.talk();
    }

    @Override
    public void hear() {
        mEar.hear();
    }

    @Override
    public void smell() {
        mNose.smell();
    }
}
//子系统,嘴
class Mouth {
    public void talk() {
        System.out.println("use Mouth to talk");
    }
}
//子系统,耳
class Ear {
    public void hear() {
        System.out.println("use Ear to hear");
    }
}
//子系统,鼻
class Nose {
    public void smell() {
        System.out.println("use Nose to smell");
    }
}

14,桥接模式

Android与设计模式(4)外观/桥接/MVP_第2张图片
桥接模式

使用场景:

可以自由拼合不同的抽象的实现,最终生成一个组合而成的实例。
桥接模式和适配器模式有点像,都像是一个组装车间,将不同的组件组装在一起。但适配器模式中,客户端只需要往里放固定的几种原料(类型是不变的),不涉及排列组合的原料选择;而桥接模式需要客户端自己选择原料的类型(抽象的种类不变,但具体实现的类型是可变的)。

Android中的应用:

Paint中桥接了颜色、粗细和样式等,可以自由拼合成我们想要的画笔。

组成部分

抽象1 | 抽象1的实现 | 抽象2 | 抽象2的实现 ... | 桥接类

代码示例:

//桥接类,画笔。桥接了颜色、画笔大小和样式
class Paint {
    private Color color;
    private Width width;
    private Style style;

    public Paint() {}
    public Paint(Color color, Width width, Style style) {
        this.color = color;
        this.width = width;
        this.style = style;
    }
    public void setColor(Color color) {
        this.color = color;
    }
    public void setWidth(Width width) {
        this.width = width;
    }
    public void setStyle(Style style) {
        this.style = style;
    }

    public void draw() {
        StringBuffer sb = new StringBuffer();
        System.out.println(sb.append(width.draw()).append(style.draw()).append(color.draw()).toString() + "画笔");
    }
}
//颜色抽象和具体实现
interface Color {
    String draw();
}
class Red implements Color {
    @Override
    public String draw() {
        return "红色";
    }
}
class Green implements Color {
    @Override
    public String draw() {
        return "绿色";
    }
}
//画笔大小抽象和具体实现
interface Width {
    String draw();
}
class BigWidth implements Width {
    @Override
    public String draw() {
        return "粗笔";
    }
}
class LittleWidth implements Width {
    @Override
    public String draw() {
        return "细笔";
    }
}
//样式抽象和具体实现
interface Style {
    String draw();
}
class FillStyle implements Style {
    @Override
    public String draw() {
        return "填充式";
    }
}

15,MVP模式

MVP模式

使用场景:

视图和业务功能的解耦。通过MVP模式,我们可以获得更清晰的模块划分和解耦,这样在多人协作时,可以更高效地明确职责。

Android中的应用:

在Android下,layout.xml就是View层。数据层可以由数据库与网络数据构成Model,但Model层要完全表达数据的输入与输出。Activity就是Present层。
RecycleView中的ViewHolder更进一步,ViewModel代替了Present,View单向地访问ViewModel。

组成部分

Model-View-Presenter
有的框架会 在Model侧创建一个外观模式的Manager,来为不同的Model功能模块提供统一的接口,类似下图:


Android与设计模式(4)外观/桥接/MVP_第3张图片
加入外观模式的MVP

代码示例:

调用方式

        //V
        IView mvpView = new LoginView();
        //M
        ICheckModel checkModel = new UserCheckModel();
        IDBModel dbModel = new DBModel();
        IDataManager dataManager = new DataManager(dbModel,checkModel);
        //P,P会关联V和M
        IPresenter presenter = new MVPPresenter(dataManager);
        presenter.onAttach(mvpView);
        mvpView.attachPresenter(presenter);
        //由View发起的调用 V -> P -> M -> P -> V
        mvpView.clickLogin();

MVP构建

//V
interface IView {
    //注入Presenter
    void attachPresenter(IPresenter presenter);
    //功能函数
    void clickLogin();
    void showMessage(String message);
}
class LoginView implements IView {
    private IPresenter mPreseter;

    @Override
    public void attachPresenter(IPresenter presenter) {
        mPreseter = presenter;
    }

    @Override
    public void clickLogin() {
        mPreseter.login();
    }

    @Override
    public void showMessage(String message) {
        System.out.println("View msg :" + message);
    }
}
//M
interface ICheckModel {
    boolean checkLogin();
}
class UserCheckModel implements ICheckModel {

    @Override
    public boolean checkLogin() {
        System.out.println("Model checkLogin :" + true);
        return true;
    }
}
interface IDBModel {
    void insertDB();
}
class DBModel implements IDBModel {

    @Override
    public void insertDB() {
        System.out.println("Model insertDB");
    }
}
//外观模式,包含所有Model,集中所有对外暴露的API
interface IDataManager {
    //注入Presenter
    void attachPresenter(IPresenter presenter);
    void login();
}
class DataManager implements IDataManager {
    private IPresenter mPreseter;
    private IDBModel mDBModel;
    private ICheckModel mCheckModel;

    public DataManager(IDBModel mDBModel, ICheckModel mCheckModel) {
        this.mDBModel = mDBModel;
        this.mCheckModel = mCheckModel;
    }

    @Override
    public void attachPresenter(IPresenter presenter) {
        mPreseter = presenter;
    }

    @Override
    public void login() {
        //检查用户合法性并将登陆操作写入DB保存
        mCheckModel.checkLogin();
        mDBModel.insertDB();
    }
}
//P
interface IPresenter {
    //关联 取消关联View
    void onAttach(V view);
    void onDetach(V view);
    void login();
}
class MVPPresenter implements IPresenter {
    private IView mView;
    private IDataManager mDataManager;

    public MVPPresenter(IDataManager dataManager) {
        mDataManager = dataManager;
    }

    @Override
    public void onAttach(V view) {
        mView = view;
    }

    @Override
    public void onDetach(V view) {
        mView = null;
    }

    @Override
    public void login() {
        //来自View的调用,先调用Model,再向View发消息
        mDataManager.login();
        mView.showMessage("login OK");
    }
}

你可能感兴趣的:(Android与设计模式(4)外观/桥接/MVP)