看了一下moock的《Essential.Actionscript.2.0》,全书都写得不错,不愧为actionscript的权威写出来的书。注意了一下,MVC模式这一章。MVC也不是什么新概念了, 早在smalltalk中开始流行了, 现在C++中的document/view结构也是这种原理。通过消息映射达到从view响应的事件改变document的内容。一看moock的写法,就知道他是有java背景的人,包括Oberserable类和Oberserver接口,以及MVC的实现都是仿照传统的java写法。
关于MVC,这里有一篇权威说明: http://st-www.cs.uiuc.edu/users/smarch/st-docs/mvc.html
我也用moock的方法,依照原来的一个java例子,做了个显示温度的,分华氏温度和摄氏温度显示。它们所用的Model和Control却是一样的,只不过View 的表现不同。 这就是MVC的优势所在。还有一个用温度计来显示的View,可以用我的com.flashvan.Graphic类来实现,下次做完把源码一起放上来。utils包和mvc包里面的内容我就省略了,可以到moock的网站下载 http://moock.org/eas2/examples/eas2_mvcclock.zip
pre {font-family:"Courier New", Courier, Arial; font-size: 12px;}
.operator {color: #000000;}
.keyword {color: #993300;}
.identifier {color: #000087;}
.properties {color: #000087;}
.identifier2 {color : #000087;}
.linecomment, .blockcomment {color: #808080;}
.string {color: #0000FF;}
//Model
import util.Observable;
import temperature.*;
class temperature.TemperatureModel extends Observable
{
private var temperatureF: Number = 32.0;
public function getF(): Number
{
return temperatureF;
}
public function getC(): Number
{
return (temperatureF - 32.0) * 5.0 / 9.0;
}
public function setF(tempF: Number ): Void
{
temperatureF = tempF;
setChanged();
notifyObservers();
}
public function setC(tempC: Number ): Void
{
temperatureF = tempC * 9.0 / 5.0 + 32.0;
setChanged();
notifyObservers();
}
}
//View base
import util.*;
import temperature.*;
import mvc.*;
import mx . containers . Window ;
import mx .controls. Button ;
import mx .controls. TextInput ;
import mx .controls. Label ;
import mx . managers .DepthManager;
class temperature.TemperatureGUI extends AbstractView
{
private var temperatureWindow: Window ;
private var label : Label ;
private var display: TextInput ;
private var upBtn: Button ;
private var downBtn: Button ;
private var temperatureGUI_mc: MovieClip ;
private function TemperatureGUI(l: String ,m:TemperatureModel, c:Controller, target : MovieClip , depth: Number , x: Number , y: Number )
{
super (m, c);
makeTemperatureGUI(l, target , depth, x, y);
}
private function makeTemperatureGUI(l: String , target : MovieClip , depth: Number , x: Number , y: Number ): Void
{
//建立一个空的MovieClip
temperatureGUI_mc = target . createEmptyMovieClip ( "gui" +depth, depth);
//temperatureGUI_mc._x = x;
//temperatureGUI_mc._y = y;
//窗口
temperatureWindow =temperatureGUI_mc. createClassObject ( Window , "temperatureWindow" , 0);
temperatureWindow. title = l+ " 温度显示" ;
temperatureWindow. move (x,y);
temperatureWindow. setSize (250,200);
//标签
label = temperatureWindow.createClassChildAtDepth( Label , DepthManager.kTop);
label . text = l+ "温度为:" ;
label . move (20,50);
//文本显示框
display = temperatureWindow.createClassChildAtDepth( TextInput , DepthManager.kTop);
display. editable = false ;
display. setSize (200,display. height );
display. move ( label .x, label .y+ label . height +10);
//升温按钮
upBtn = temperatureWindow.createClassChildAtDepth( Button , DepthManager.kTop);
upBtn. label = "升温" ;
upBtn. setSize (60,upBtn. height );
upBtn. move (display.x+30,display.y+display. height +10);
upBtn. addEventListener ( "click" , getController());
//降温按钮
downBtn = temperatureWindow.createClassChildAtDepth( Button , DepthManager.kTop);
downBtn. label = "降温" ;
downBtn. setSize (60,downBtn. height );
downBtn. move (upBtn.x+upBtn. width +10,upBtn.y);
downBtn. addEventListener ( "click" , getController());
update();
}
public function defaultController (model:Observable):Controller
{
return new TemperatureController(model);
}
public function setDisplay (s: String ): Void { display. text =s;}
public function getDisplay(): Number
{
//var result:Number = 0.0;
var result : Number = Number (display. text );
return result ;
}
public function update (o:Observable, infoObj: Object ): Void
{
}
}
//Farenheit View
import util.*;
import temperature.*;
import mvc.*;
class temperature.FarenheitGUI extends TemperatureGUI
{
public function FarenheitGUI(m:TemperatureModel, c:Controller, target : MovieClip , depth: Number , x: Number , y: Number )
{
super ( "华氏" , m, c, target ,depth,x,y);
//setDisplay(""+model.getF());
}
public function update (o:Observable, infoObj: Object ): Void
{
setDisplay( "" + TemperatureModel(getModel()).getF());
}
}
//Celsius View
import util.*;
import temperature.*;
import mvc.*;
class temperature.CelsiusGUI extends TemperatureGUI
{
public function CelsiusGUI(m:TemperatureModel, c:Controller, target : MovieClip , depth: Number , x: Number , y: Number )
{
super ( "摄氏" , m, c, target ,depth,x,y);
//setDisplay(""+model.getF());
}
public function update (o:Observable, infoObj: Object ): Void
{
setDisplay( "" + TemperatureModel(getModel()).getC());
}
}
//Controller
import temperature.TemperatureModel;
import mvc.*;
import util.*;
class temperature.TemperatureController extends AbstractController
{
public function TemperatureController (tm:Observable)
{
super (tm);
}
public function upTemperature()
{
var m:TemperatureModel= TemperatureModel(getModel());
m.setF(m.getF()+1);
}
public function downTemperature()
{
var m:TemperatureModel= TemperatureModel(getModel());
m.setF(m.getF()-1);
}
public function click (e: Object ): Void
{
switch (e. target . label )
{
case "升温" : upTemperature();
break ;
case "降温" : downTemperature();
break ;
default :
break ;
}
}
}
//主程序
import temperature.*;
class temperature.Thermometer
{
//程序入口
public static function main ( target : MovieClip ,f: Number )
{
var tm:TemperatureModel = new TemperatureModel();
var fg:FarenheitGUI = new FarenheitGUI(tm, undefined , target , 2, 10, 50);
var cg:CelsiusGUI = new CelsiusGUI(tm, undefined , target , 3, 300, 50);
tm.addObserver(fg);
tm.addObserver(cg);
if (f!= undefined ) tm.setF(f);
}
}
//*.fla
import temperature.Thermometer;
Thermometer.main( this );
在fla文件中要拖出Window,Button,TextInput,Label这四个组件在放在库中,要不然不能显示