观察者模式的应用:模拟MVC架构的实现
Posted 辉猿走壁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式的应用:模拟MVC架构的实现相关的知识,希望对你有一定的参考价值。
之前讲过观察者模式,今天想讲下观察者模式的一个典型应用场景,MVC架构的实现。
首先,简单说下什么是MVC。
MVC是model,view和controller三个对象的简称,基于职责分离的原则,三者分别承担不同的工作。
view:负责界面显示逻辑 model:负责数据封装以及相关业务逻辑 controller:view与mode的中间者,负责传递事件,有时候可承担简单的业务逻辑
当用户操作界面时,比如点击某个按钮,会把点击事件传给controller,controller通知model进行更新,当model更新完毕后,需要通知view来刷新界面。
因此,model和view需要有一套机制来保证model的数据变更能够实时同步到view显示。
所以,观察者模式便在mvc模式中派上了用场。
MVC架构的依赖关系图
MVC架构的调用关系图
基于MVC架构的依赖关系和调用关系图,我用java程序来简单模拟MVC架构的实现。
首先看看类图:
简单讲解下每个类的作用:
观察类图会发现自顶向下分成了三个层次:
1.顶层抽象:定义观察者抽象层代码和view,model的基本行为接口。
IObserver:抽象观察者接口 IObservable:抽象被观察者接口 IViewAction:视图行为接口,定义视图的基本行为 IModelAction:Model行为接口,定义model的基本操作
2.view,model抽象层
BaseView:view基类,view的抽象层,实现IObserver接口
BaseModel:model基类,model的抽象层,实现IObservable接口
3.具体实现层
Controller:控制器,依赖于BaseView和BaseModel,通过抽象依赖的方式,与具体view和具体model解耦,使得controller更容易复用
view:具体view,继承BaseView
Model:具体model,继承BaseModel。
然后这是源代码,注释已经写得很清楚,我就不解释了:
IObserver:
/**
* 观察者接口
*/
public interface IObserver {
/**
* 观察者方法
* @param subject:被观察者抽象层对象
* @param o:额外信息
*/
public void update(IObservable observable, Object o);
}
IObservable:
/**
* 被观察者接口
*/
public interface IObservable {
public void addObserver(IObserver observer);
public void deleteObserver(IObserver observer);
public void notifyUpdate();
public void notifyUpdate(Object object);
}
IViewAction:
/**
* 定义视图的基本行为
*/
public interface IViewAction {
/**
* 刷新视图
* @param baseModel
* @param o
*/
public void refreshView(BaseModels baseModel, Object o);
}
IModelAction:
/**
* 定义model的基本行为
*/
public interface IModelAction {
/**
* model请求数据
*/
public void requestData();
}
BaseView:
public abstract class BaseViews implements IObserver,IViewAction{
protected Controller controller;// 控制器
public BaseViews() {
controller = new Controller(this);
}
@Override
public void update(IObservable observable, Object o) {
if(observable instanceof BaseModels) {
BaseModels baseModel=(BaseModels)observable;
if(baseModel.isChanged()) {
refreshView(baseModel,o);
}
}
}
}
BaseModel:
public abstract class BaseModels implements IObservable, IModelAction {
private List<IObserver> mObservers;
private boolean mIsChanged;
public BaseModels() {
mObservers = new ArrayList<IObserver>();
}
@Override
public void addObserver(IObserver observer) {
if (mObservers == null) {
return;
}
mObservers.add(observer);
}
@Override
public void deleteObserver(IObserver observer) {
if (mObservers == null || mObservers.size() == 0) {
return;
}
mObservers.remove(observer);
}
@Override
public void notifyUpdate() {
notifyUpdate(null);
}
@Override
public void notifyUpdate(Object object) {
if (mObservers == null || mObservers.size() == 0) {
return;
}
for (IObserver observer : mObservers) {
observer.update(this, object);
}
}
public boolean isChanged() {
return mIsChanged;
}
public void setChanged(boolean mIsChanged) {
this.mIsChanged = mIsChanged;
}
}
Controller:
public class Controller {
private BaseViews view;
private BaseModels model;
public Controller(BaseViews view) {
super();
this.view = view;
model = new Model();
// 将view与model绑定
model.addObserver(view);
}
public void doSomething() {
System.out.println("controller响应view的界面操作事件,通知model更新");
model.requestData();
}
}
View:
public class View extends BaseViews {
public void touch() {
System.out.println("模拟屏幕操作,触发响应事件,将事件传给controller处理");
// 将事件传给controller处理
controller.doSomething();
}
/**
* 刷新界面
*/
@Override
public void refreshView(BaseModels baseModel, Object o) {
if (baseModel instanceof Model) {
Model model = (Model) baseModel;
String name = model.getName();
String display = model.getDisplay();
System.out.println("收到Model通知,更新界面");
System.out.println("Model包含以下数据:");
System.out.println("name=" + name + " ,display=" + display);
}
}
}
Model:
public class Model extends BaseModels {
/**
* Model的一些属性
*/
private String name;// 名字
private String display;// 展示数据
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
@Override
public void requestData() {
// 模拟model更新
setName("杰伦");
setDisplay("哎呦,不错哦");
// 设置改变
setChanged(true);
System.out.println("model发生了改变,通知view更新");
notifyUpdate();
}
}
Client:
public class Client {
public static void main(String[] args) {
View view = new View();
// 模拟点击界面
view.touch();
}
}
运行截图:
总结
本来想真正写个安卓程序来实现mvc模式的,但是因为想着方便点就直接用java实现了,所以view是假的view,只是用来模拟用户操作而已。虽然并不是真正的安卓程序,但是这些代码还是具备可移植性的,如果想在安卓程序上应用只需要把view换成真正的view就可以了,其他代码视情况进行适当修改。
可扩展性分析
假如以后想增加新的view和mode,,则只需要增加新的子类,分别继承Baseviewh和BaseModel即可,不需要修改源代码,controller也不需要改,因为controler依赖于BaseView和BaseModel,并不依赖于具体类,符合开闭原则。
缺点
存在多层依赖关系,自顶向下存在三层依赖关系:观察者抽象层:IObserver依赖于IObservable view,model抽象层:BaseView依赖于BaseModel 具体实现层:View依赖于Model 由于这样的关系,所以需要多次使用instanceof进行强制类型转换,影响效率。
https://github.com/hyhdy/mvc_java
长按二维码关注
辉猿走壁码出奇迹
以上是关于观察者模式的应用:模拟MVC架构的实现的主要内容,如果未能解决你的问题,请参考以下文章