Android与设计模式(4)外观/桥接/MVP
详细代码请见https://github.com/zackLangChina/DesignPatternLearning
Android与设计模式(1)
单例模式 ** 工厂模式 ** 策略模式 ** 命令模式
Android与设计模式(2)
观察者模式 ** 备忘录模式 ** 模板方法模式 ** 中介者模式
Android与设计模式(3)
代理模式 ** 适配器模式 ** 装饰模式 ** 享元模式
Android与设计模式(4)
外观模式 ** 桥接模式 ** MVP模式
13,外观模式

使用场景:
隐藏一系列小系统组成的大系统的复杂性,并向客户端提供了一个客户端可以访问这些系统的接口。客户端不与系统耦合,外观类与系统耦合。
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中的应用:
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模式,我们可以获得更清晰的模块划分和解耦,这样在多人协作时,可以更高效地明确职责。
Android中的应用:
在Android下,layout.xml就是View层。数据层可以由数据库与网络数据构成Model,但Model层要完全表达数据的输入与输出。Activity就是Present层。
RecycleView中的ViewHolder更进一步,ViewModel代替了Present,View单向地访问ViewModel。
组成部分
Model-View-Presenter
有的框架会 在Model侧创建一个外观模式的Manager,来为不同的Model功能模块提供统一的接口,类似下图:

代码示例:
调用方式
//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<V extends IView> {
//关联 取消关联View
void onAttach(V view);
void onDetach(V view);
void login();
}
class MVPPresenter<V extends IView> implements IPresenter<V> {
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");
}
}