AS3 mvc应用
短信预约 -IT技能 免费直播动态提醒
在程序开发中,为了降低程序的耦合度,我们经常会对程序进行模式化,这一节中,我们介绍MVC的设计模式,MVC由三层结构构成,分别是视图器(view),模型器(model),控制器(control)。视图器view的作用是显示对象,即我们肉眼看到的元素。而视图器需要的数据我们把它放到模型器model里,那如何操作这些数据呢,这便涉及到我们的逻辑,我们把这部分的程序放进控制器control里。所以,实际上是控制器control在操作模型器model,使其发生数据的改变,而引起model发出相应的事件,视图器view侦听到这些事件时相应的改变视图。应用MVC的结构可以让我们的程序更加有条理更加清晰。下面是一个MVC的小例子。由三个类跟一个文档类构成:
这个例子主要是:点击按钮时让文本的数据加100.功能很简单。
首先是视图类:MyView.as. 它只有一个按钮跟一个文本。当点击按钮时,我们调用control的方法changeNum。同时,我们在MyView监听model的数据改变事件。
package View
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.*;
import Model.MyModel;
import Control.MyControl;
public class MyView extends Sprite
{
private var _model:MyModel;
private var _control:MyControl;
private var _showBtn:CustomSimpleButton;
private var _showLabel:TextField ;
public function MyView(model:MyModel,control:MyControl)
{
this._model = model, this._control = control;
initConfig();//初始化界面
initListener();//添加侦听器
}
private function initConfig():void {
_showBtn = new CustomSimpleButton();
_showBtn.x = 50, _showBtn.y = 50;
this.addChild(_showBtn);
_showLabel = createTextField(0, 20, 200, 20);
_showLabel.x = 50, _showLabel.y = 30;
_showLabel.text = "2";
this.addChild(_showLabel)
}
private function initListener():void {
this._showBtn.addEventListener(MouseEvent.CLICK, mouseClick)
//注册模型器的监听
_model.addEventListener("changeStr", showText);
}
//视图器触发 控制器的方法changeNum
private function mouseClick(e:MouseEvent):void {
_control.changeNum(uint(_showLabel.text))
}
public function showText(evt:Event) :void{
_showLabel.text = String(_model.ModelNum);
}
private function createTextField(x:Number, y:Number, width:Number, height:Number):TextField {
var result:TextField = new TextField();
result.x = x; result.y = y;
result.width = width; result.height = height;
addChild(result);
return result;
}
}
}
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.SimpleButton;
class CustomSimpleButton extends SimpleButton {
private var upColor:uint = 0xFFCC00;
private var overColor:uint = 0xCCFF00;
private var downColor:uint = 0x00CCFF;
private var size:uint = 40;
public function CustomSimpleButton() {
downState = new ButtonDisplayState(downColor, size);
overState = new ButtonDisplayState(overColor, size);
upState = new ButtonDisplayState(upColor, size);
hitTestState = new ButtonDisplayState(upColor, size * 2);
hitTestState.x = -(size / 4);
hitTestState.y = hitTestState.x;
useHandCursor = true;
}
}
class ButtonDisplayState extends Shape {
private var bgColor:uint;
private var size:uint;
public function ButtonDisplayState(bgColor:uint, size:uint) {
this.bgColor = bgColor;
this.size = size;
draw();
}
private function draw():void {
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}
}
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.*;
import Model.MyModel;
import Control.MyControl;
public class MyView extends Sprite
{
private var _model:MyModel;
private var _control:MyControl;
private var _showBtn:CustomSimpleButton;
private var _showLabel:TextField ;
public function MyView(model:MyModel,control:MyControl)
{
this._model = model, this._control = control;
initConfig();//初始化界面
initListener();//添加侦听器
}
private function initConfig():void {
_showBtn = new CustomSimpleButton();
_showBtn.x = 50, _showBtn.y = 50;
this.addChild(_showBtn);
_showLabel = createTextField(0, 20, 200, 20);
_showLabel.x = 50, _showLabel.y = 30;
_showLabel.text = "2";
this.addChild(_showLabel)
}
private function initListener():void {
this._showBtn.addEventListener(MouseEvent.CLICK, mouseClick)
//注册模型器的监听
_model.addEventListener("changeStr", showText);
}
//视图器触发 控制器的方法changeNum
private function mouseClick(e:MouseEvent):void {
_control.changeNum(uint(_showLabel.text))
}
public function showText(evt:Event) :void{
_showLabel.text = String(_model.ModelNum);
}
private function createTextField(x:Number, y:Number, width:Number, height:Number):TextField {
var result:TextField = new TextField();
result.x = x; result.y = y;
result.width = width; result.height = height;
addChild(result);
return result;
}
}
}
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.SimpleButton;
class CustomSimpleButton extends SimpleButton {
private var upColor:uint = 0xFFCC00;
private var overColor:uint = 0xCCFF00;
private var downColor:uint = 0x00CCFF;
private var size:uint = 40;
public function CustomSimpleButton() {
downState = new ButtonDisplayState(downColor, size);
overState = new ButtonDisplayState(overColor, size);
upState = new ButtonDisplayState(upColor, size);
hitTestState = new ButtonDisplayState(upColor, size * 2);
hitTestState.x = -(size / 4);
hitTestState.y = hitTestState.x;
useHandCursor = true;
}
}
class ButtonDisplayState extends Shape {
private var bgColor:uint;
private var size:uint;
public function ButtonDisplayState(bgColor:uint, size:uint) {
this.bgColor = bgColor;
this.size = size;
draw();
}
private function draw():void {
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}
}
其次是控制器类:MyControl.as,这里的操作视图器model,我们可以做更复杂的逻辑控制,这里我们简单化,只是让数据加100。
package Control
{
import View.MyView;
import Model.MyModel;
public class MyControl
{
private var _model:MyModel;
public function MyControl(model:MyModel)
{
this._model = model;
}
public function changeNum(n:uint):void
{
//模型发出事件通知
var temp:uint = n +100
_model.showNum(temp);
}
}
}
{
import View.MyView;
import Model.MyModel;
public class MyControl
{
private var _model:MyModel;
public function MyControl(model:MyModel)
{
this._model = model;
}
public function changeNum(n:uint):void
{
//模型发出事件通知
var temp:uint = n +100
_model.showNum(temp);
}
}
}
再次是模型器MyModel.as,在这里我们可以根据程序需要定义不同的数据,这里我们的功能只需要一个textField需要的数据,我们定义为_ModelNum。当_ModelNum发生改变时,我们发出一个changeStr的事件,告诉视图器该修改显示元素啦。
package Model
{
import flash.events.Event;
import flash.events.EventDispatcher;
public class MyModel extends EventDispatcher
{
private var _ModelNum:uint;
public function MyModel()
{
}
public function get ModelNum():uint
{
return _ModelNum;
}
//在控制器中调用此方法 。模型器发送数据更改的事件。
public function showNum(n:uint):void
{
_ModelNum = n;
//修改
dispatchEvent(new Event("changeStr"));
}
}
}
{
import flash.events.Event;
import flash.events.EventDispatcher;
public class MyModel extends EventDispatcher
{
private var _ModelNum:uint;
public function MyModel()
{
}
public function get ModelNum():uint
{
return _ModelNum;
}
//在控制器中调用此方法 。模型器发送数据更改的事件。
public function showNum(n:uint):void
{
_ModelNum = n;
//修改
dispatchEvent(new Event("changeStr"));
}
}
}
在上面,我们已经将程序的结构MVC化,最后我们还需要一个文档类MvcDoc.as,它将实例化我们的MVC三个结构部分。
package
{
import flash.display.Sprite;
import flash.events.Event;
import View.MyView;
import Control.MyControl;
import Model.MyModel;
public class MvcDoc extends Sprite
{
private var _model:MyModel;
private var _controller:MyControl;
private var _view:MyView;
public function MvcDoc():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
_model = new MyModel();
_controller = new MyControl(_model);
_view = new MyView(_model,_controller);
addChild(_view);
removeEventListener(Event.ADDED_TO_STAGE, init);
}
}
}
{
import flash.display.Sprite;
import flash.events.Event;
import View.MyView;
import Control.MyControl;
import Model.MyModel;
public class MvcDoc extends Sprite
{
private var _model:MyModel;
private var _controller:MyControl;
private var _view:MyView;
public function MvcDoc():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
_model = new MyModel();
_controller = new MyControl(_model);
_view = new MyView(_model,_controller);
addChild(_view);
removeEventListener(Event.ADDED_TO_STAGE, init);
}
}
}
最后,我们往往会提出一个疑问:不就是一个点击按钮然后改变文本数据的功能么,直接在视图类监听按钮的事件,直接改变不就行了?为什么搞那么复杂呢?如果这样,会很容易出现以下两个缺点:1,设计逻辑制作混乱,这需要开发者有高度清晰的思路,而且还要防止各段代码之间的相互影响。2,维护起来费时、费力,可能开发者对他们的代码很熟悉,某个功能可以很快的找到,但换个人进行维护,可能读代码如读天书,修改一个小小的功能可能都是噩梦。当我们在开发大项目时,这样的划分可以让我们的程序OOP面向对象化,视图层与控制层割开来,那么开发起来就更加方便维护更加有条理性.
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341