iptton 发表于 2007-7-14 14:39

about MVC

没五笔打真痛苦.....




readinga 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();
                }
      }
}

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

[ 本帖最后由 iptton 于 2007-7-18 21:25 编辑 ]

iptton 发表于 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 AbstractClockViewextends 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 编辑 ]

iptton 发表于 2007-7-14 14:58

leftsome files my computer.....

to be continue...

xinggg22 发表于 2007-7-14 22:50

iptton 发表于 2007-7-15 12:01

source code will be uploaded to   GMAIL:

                     gdutbbspro@gmail.com
password:    gdutbbs.com
页: [1]
查看完整版本: about MVC