模型-视图-控件(model-View-Controller)MVC结构是一种开发模块的方法,它将数据存储和数据处理从数据的可视化表示中分离出来。存储和处理数据的组件称为模型,它包括模块的实际内容。表示数据的组件称为视图,它处理模块全部必要的行为,完毕模块的全部显示。控件一般是一种用来获取数据的组件。

把模块分解成模型与视图有两个明显长处:

1.能够使用多个视图共享同一个模型数据。

2.能够简化复杂应用程序的编写,使用模块具有可伸缩性,而且易于维护。能够改动视图但不会影响模型,反之亦然。

使用MVC最重的一点是,因模型包包括数据,视图显示数据,所以一旦一个视图与模型建立联系,它一定要与该模型同步。

模型数据改变了通知视图,视图接受通知,更新受影响的视图区域。

这里能够使用前面一篇文章介绍的观察者模式实现,假设读者者对java 事件托付模型了解的话也能够使用这样的方式去实现。

MVC另一种变体就是将控件和视图结合在一起。在这样的情况下,视图不仅显示数据,也作为接口和用户进行交互,接受用户的输入。例如以下图所看到的:

这样的变体模式,如是读者做ios开发,应该对种变体模式非常了解的, IOS应用架构就是遵循这样的变体MVC。

以下呈上一个这个种变体模式Demo,模型通知视图更新这一步,是用java 事件托付模型实现,在这里为了兼顾有些读者对这这个模型不了解,就简单的介绍下:

事件源对象触发一个事件,对此事件感兴趣的对象会处理它,对此事件感兴趣的对象称为监听器,意思是把事件托付给监听器处理。

view组件

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View; public class CircleView extends View implements ActionListener {
private CircleModel model; public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public CircleModel getModel() {
return model;
} public void setModel(CircleModel model) {
this.model = model;
if (model != null) {
model.addActionListener(this);
invalidate();
}
} @Override
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
invalidate();
} @Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub super.draw(canvas);
if (model == null) {
return;
}
int width = getWidth();
int height = getHeight();
Paint paint = new Paint();
canvas.drawCircle(width / 2, height / 2, (float)model.getRadius(), paint);
}
}

model组件

package com.example.learn;

import java.util.ArrayList;

public class CircleModel {
private static final int DEFAULT_RADIUS = 20;
private double radius = DEFAULT_RADIUS;
private ArrayList<ActionListener> actionListeners;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
processEvent(new ActionEvent(this, ActionEvent.UPDATE, "radius"));
} public void addActionListener(ActionListener listener) {
if (actionListeners == null) {
actionListeners = new ArrayList<ActionListener>();
} actionListeners.add(listener);
} public void removeActionListener(ActionListener listener) {
if(actionListeners != null && actionListeners.contains(listener)) {
actionListeners.remove(listener);
}
} private void processEvent(ActionEvent event) {
ArrayList list = null;
synchronized (this) {
if(actionListeners == null) {
return;
}
list = (ArrayList) actionListeners.clone();
} for(int i = 0; i < list.size(); i++) {
ActionListener listener = (ActionListener) list.get(i);
listener.actionPerformed(event);
}
} } class ActionEvent {
public static final byte UPDATE = 0x01;
public ActionEvent(Object source, byte type, String eventDesc) { }
} interface ActionListener {
public void actionPerformed(ActionEvent event);
}

controller组件

package com.example.learn;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText; public class CircleController extends Activity {
private CircleModel model;
private CircleView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (CircleView) findViewById(R.id.circle_view);
model = new CircleModel();
model.addActionListener(view);
view.setModel(model);
View setRadius = findViewById(R.id.radius_bn);
final EditText radiusEt = (EditText) findViewById(R.id.radius_et);
setRadius.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
double radius = Double.parseDouble(radiusEt.getText().toString());
model.setRadius(radius);
}
});
}
}

最新文章

  1. Linux学习笔记之兄弟连
  2. SQL 常用脚本
  3. Orchard源码分析(7.1):Routing(路由)相关
  4. POJ 1062 昂贵的聘礼 最短路 难度:0
  5. HDFS知识体系 思维导图
  6. C语言创建并使用dll
  7. winscp连接vmware ubuntu
  8. HDU 3339 最短路+01背包
  9. params修饰符
  10. C# 类型、存储和变量
  11. Mac下brew安装JDK的教程
  12. Unity3D|-XLua热更新用法的大致流程
  13. EF Core中DbContext可以被Dispose多次
  14. GDCPC 2008:B Reading books
  15. RedisTemplate Redis 操作
  16. 使用python识别验证码
  17. Qt-网易云音乐界面实现-5 收藏列表,播放列表实现 QListWidget QTableWidget
  18. javascript reg 不加入分组
  19. Java50道经典习题-程序11 求不重复数字
  20. c#基础 第八讲

热门文章

  1. ANSCII码和BCD码互转
  2. js中退出语句break,continue和return 比较 (转)
  3. 【55.70%】【codeforces 557A】Ilya and Diplomas
  4. 【27.85%】【codeforces 743D】Chloe and pleasant prizes
  5. Visual Studio 项目目录下的bin目录和 obj目录
  6. ETL概述 分类: H2_ORACLE 2013-08-23 10:36 344人阅读 评论(0) 收藏
  7. php求二叉树的深度(1、二叉树就可以递归,因为结构和子结构太相似)(2、谋而后动,算法想清楚,很好过的)
  8. 第一次使用docker for windows 遇到的坑
  9. 关于pptpd log日志文件的配置
  10. 【a502】符号三角形问题