现在的位置: 首页 > 综合 > 正文

AS3.0 MVC pattern

2013年11月11日 ⁄ 综合 ⁄ 共 10225字 ⁄ 字号 评论关闭
 reading  a book about ActionScript3.0 Design Pattern

The first chapter's about MVC pattern...

The book uses an example about CLOCK

I've code a version without MVC pattern for comparision:(2F show the MVC...)

=================================================
=================================================
the simplest version is:
1.. draw 3 Dynamic TextField whose instance's name's tf_hours,tf_minutes and tf_secondes

2.. frame 1 actionScript:

setInterval(runClock,1000);
function runClock(){
    var d:Date=new Date();
    tf_hours.text=d.getHours().toString();
    tf_minutes.text=d.getMinutes().toString();
    tf_seconds.text=d.getSeconds().toString();
}

3.. ctrl+ enter    DONE....

==================================================

the version with document class (can be use in FLEX also)

引用

  package {
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.utils.setInterval;
        
        public class SimpleClock extends Sprite {

                /**
                 * SimpleClock类,MVC不分开
                 *  用法:
                 *    设一个AS3.0Fla 文件的DOcumentClass为 SimpleClock
                 *    (如果fla与SimpleClock.as不在同一路径,要先设置类路径)
                 */

                // "View"
                private var tf_hours:TextField;
                private var tf_minutes:TextField;
                private var tf_seconds:TextField;

                public function SimpleClock() {
                        //
                        // 构造函数
                        //    As3.0的Document Class的构造函数
                        //    相当于 JAVA 里的 public static main()入口函数
                        //

                        init();
                        
                        /**
                         此处建议是用Timer类(与JAVA类似),
                         为求简单,(setInterval与javascript里的用法一样)
                         这里暂时用旧的函数方法。
                         Flash自带help里的说明:
                         Instead of using the setInterval() method,
                         consider creating a Timer object,
                         with the specified interval,
                         using 0 as the repeatCount parameter
                         (which sets the timer to repeat indefinitely).                        
                         */

                        setInterval(runing,1000);
                }
                private function init() {
                        /**
                         *  界面初始化,
                         *  没有用类的最简单版是直接在
                         *  FLASH_IDE上画以下三个 Dynamic TextField
                         *
                         *  此版本也可以这样,
                         *  但这里为了方便说明View
                         *  不直接在IDE上画
                         *  同时,一个Document Class
                         *  似乎也是不应该对引用其的FLA有接口限制(不知这样想对不对..)
                         *
                         */

                        tf_hours   = new TextField();
                        tf_minutes = new TextField();
                        tf_seconds = new TextField();

                        tf_hours.x   = 120;
                        tf_minutes.x = 140;
                        tf_seconds.x = 160;
                        tf_hours.y=tf_minutes.y=tf_seconds.y = 100;

                        addChild(tf_hours);
                        addChild(tf_minutes);
                        addChild(tf_seconds);
                }
                private function runing() {
                        /******************
                        此函数与最简单版的AS一样
                        *******************/

                        var d:Date=new Date();
                        tf_hours.text=d.getHours().toString();
                        tf_minutes.text=d.getMinutes().toString();
                        tf_seconds.text=d.getSeconds().toString();
                }
        }
}

====================================================
====================================================

 

 

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

 

抱歉!评论已关闭.