|
楼主 |
发表于 2007-7-14 14:50
|
显示全部楼层
The version above just show a digital clock with 3 textfields ..
when you want a graphic version (有时针的那种,don't know how to spell it... )
you may need to rewrite all the code.
and each time you wanna change it's look,
you must repeat this....
actually, I don't think it's a trouble in this example(CLOCK)....
package gdutpxz.MVCLearning{
public class Time{
/**
* Model
*/
private var m_hours:uint;
private var m_minutes:uint;
private var m_seconds:uint;
public function Time(h:uint=0,m:uint=0,s:uint=0){
m_hours = h;
m_minutes = m;
m_seconds = s;
}
//
//以下函数个人认为
//在本例中不如直接把三个成员变量设为public方便
//
public function get hour():uint{return m_hours;}
public function set hour(h:uint):void{m_hours=h;}
public function get minute():uint{return m_minutes;}
public function set minute(m:uint):void{m_minutes=m;}
public function get second():uint{return m_seconds;}
public function set second(s:uint):void{m_seconds=s;}
/**原书注解,不翻译了..
* Note that the Time class also defines a clone() method
* that returns a new Time object
* with the same time value as the original.
* The clone() method is important so that
* we can assign clones of Time objects
* rather than references to the original.
*/
public function clone():Time{
return new Time(m_hours,m_minutes,m_seconds);
}
};
}
package gdutpxz.MVCLearning{
import flash.events.Event;
import flash.events.EventDispatcher;
//原书中还有:
// import gdutpxz.MVCLearing.Time
//在同一包内的类可以不引用,
//为什么在这书上却也引用?
//这有什么好处?不解...
public class ClockData extends EventDispatcher{
/**
* 此类继承于 EventDispatcher ,
* EventDispatcher类主要有 addListener 等函数
* 此类是FLASH库中实现的 观察者模式(observer pattern)
*/
private var m_time:Time;
public function ClockData(){
//
//书中例子是空的构造函数。
//个人认为构造函数应该进行数据初始化
//而非交给客户去完成
//
var d:Date = new Date();
m_time=new Time(d.getHours(),d.getMinutes(),d.getSeconds());
dispatchEvent(new Event(Event.CHANGE));
}
public function get time():Time{
if(m_time==null){
var d:Date=new Date();
return new Time(d.getHours(),d.getMinutes(),d.getSeconds());
}else{
/*
Time 类的clone函数在此应用.
原书注解:
In both cases where the ClockData class
uses the clone() method of Time objects,
it does so to protect encapsulation(封装性).
If it didn't call clone(),
but returned a reference to the object,
then any changes to that object outside the data model
would also affect the data model.
Consider the following example:
var data:ClockData = new ClockData();
var time:Time = new Time(12, 0, 0);
data.time = time;
time.hour = 14;
trace(data.time.hour);
(我的理解)
简而言之就是保护封装性,
使Model里的数据只能通过Model提供的方式来改变
本例中是 通过 setter function time() 来修改
*/
return m_time.clone();
}
}
public function set time(t:Time):void{
m_time=t.clone();
//下面这句即为observer模式的一个应用
//发出一个动作信号: CHANGE 给观查本对象的东西.
dispatchEvent(new Event(Event.CHANGE));
}
}//class ClockData
}//package gdutpxz.MVCLearing
package gdutpxz.MVCLearning{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
public class AbstractClockView extends Sprite{
protected var m_data:ClockData;
public function AbstractClockView(d:ClockData){
m_data=d;
//
//当m_data调用了 dispatcherEvent(EVENT.CHANGE)时
// 本对象的 draw 函数执行.
//
m_data.addEventListener(Event.CHANGE,draw)
}
protected function draw(e:Event):void{
}
}//class AbstractClockView
}//package gdutpxz.MVCLearing
package gdutpxz.MVCLearning{
import flash.events.Event;
import flash.display.Sprite;
public class AnalogClock extends AbstractClockView{
/**
* 模拟挂钟
*/
private var m_face:Sprite;
private var m_hHand:Sprite; //时针
private var m_mHand:Sprite;
private var m_sHand:Sprite;
public function AnalogClock(data:ClockData){
super(data);
//===================================\\
//画钟面
m_face = new Sprite();
m_face.graphics.lineStyle(0, 0x000000, 1);
m_face.graphics.drawCircle(0, 0, 100);
//画三条针
m_hHand = new Sprite();
m_hHand.graphics.lineStyle(5, 0x000000, 1);
m_hHand.graphics.lineTo(0, -50);
m_mHand = new Sprite();
m_mHand.graphics.lineStyle(2, 0x000000, 1);
m_mHand.graphics.lineTo(0, -80);
m_sHand = new Sprite();
m_sHand.graphics.lineStyle(0, 0x000000, 1);
m_sHand.graphics.lineTo(0, -80);
//===================================\\
//添加到舞台(显示s)
//此处与书中代码略有不同
//原代码为 m_face 和三个hand都直接为
//主舞台的子元素。
//这里改成针为钟面的子元素.
m_face.addChild(m_hHand);
m_face.addChild(m_mHand);
m_face.addChild(m_sHand);
addChild(m_face);
//原文中还有一句 draw() 函数,
//此处省略,draw 函数的职能是响应 data的CHANGE事件,
//不应该直接调用
//从语义上说,data的构造函数应该触发 CHANGE事件。
//所以,回头改了ClockData的构造函数
}
//
//重写成员方法 draw
//
override protected function draw(e:Event):void{
//根据 m_data (继承自AbstractClockView的成员变量)
//绘制钟面的针的角度。
var time:Time = m_data.time;
//此处算法的公式,用初中的几何知识即可算出
m_hHand.rotation = 30*time.hour + 30*(time.minute/60);
m_mHand.rotation = 6*time.minute + 6*(time.second/60);
m_sHand.rotation = 6*time.second;
}
}//class AnalogClock
}//package gdutpxz.MVCLearing
[ 本帖最后由 iptton 于 2007-7-18 21:34 编辑 ] |
|