Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3351792
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类:

2010-06-01 16:30:33

1.项目简介
    本人准备开发一个信息管理系统,经过详细的考虑,决定采用基于parsley的MVC框架作为FLEX开发的框架。
    parsley的MVC框架的优点
        .适当解耦(视图类和视图model类、控制类与service类),提高了程序的可读性和可维护性
        .避免使用FLEX的事件传播机制,降低了系统运行的风险(过多的注册监听事件会带来意想不到的问题,比如不及时删除无用的事件监听器,会阻止垃圾回收器从而造成内存泄露,而且它们还很难跟踪并且影响程序的性能)
        .适当的对象托管会给编程带来方便
    下图所示:


    parsley的MVC框架中,一个典型的模块的包分为六个部分:视图包、视图model包、Command包、Model包、Service包、消息包。
    类与类之间的数据传递通过框架提供的消息来完成。
    由于消息类大量的与Model类重复,比如创建用户消息类CreateUserMessage中只有一个类User.从整体上看提高了程序可读性,但是加大了编码工作量,本人决定舍弃消息层,将消息包与Model包合并成Model层,比如CreateUserCommand类的参数直接使用UserModel,而不是CreateUserMessage。
部分代码说明如下:
   
取消了Message包后,
   

2.项目目录结构
src
   --默认包
       --index.mxml   //首页面
       --Config.mxml  //根配置文件
   --com.teacherHome
       --system
          --config
              --SystemConfig.mxml  //系统管理模块配置文件
          --commands
              --CreateXsCommand.as    //创建学生命令
              --DeleteBjCommand.as    //删除班级命令
          --models
              --LoginModel.as         //登录数据类
              --XsModel.as            //学生数据类
              --BjModel.as            //班级数据类
          --Services
              --XsSevice.as           //学生远程服务类
              --BjService.as          //班级远程服务类
              --mock
                   --XsServiceMock.as //学生服务测试类
                   --BjServiceMock.as //班级服务测试类
          --view
              --components
                   --CjPanel.mxml     //成绩组件
              --renderers
                   --ImageRenderer.mxml //Render组件
              --skins
                   --CjListSkin.mxml  //成绩列表皮肤组件
              SystemMain.mxml         //系统管理主页面
          --styles
              --System.css            //系统管理的CSS文件

3.视图包与视图model包
    视图类负责组织页面的组件显示,只包含组件和组件事件处理函数。视图model类注入到视图中,负责管理业务逻辑。
例:
登录视图类代码片段:
   
                    import com.adobe.system.view.LoginPM;
           
            [Bindable]
            [Inject]
            public var pm : LoginPM;//视图model类
           
            private function handleKeyDown( event : KeyboardEvent ) : void
            {
                if( event.keyCode == Keyboard.ENTER )
                {
                    pm.username=usernameInput.text;
                    pm.password=passwordInput.text;
                   
                    pm.login(username, password);
                }
            }

            protected function button1_clickHandler(event:MouseEvent):void
            {
                pm.login(username, password);  //业务逻辑也封装在视图model中
            }

        ]]>
   

   
                  verticalCenter="0">
                    keyDown="handleKeyDown( event )">
           
                                    id="usernameInput"
                    text="{ pm.username }"/>  //数据封装在视图model类中
           

           
                                    id="passwordInput"
                    text="{ pm.password }"
                    displayAsPassword="true"/>
           

       
       
                    label="Model injected?"
            labelPlacement="left"
            enabled="false"
            selected="{ pm != null }"/>
       
                    label="login"
             click="button1_clickHandler(event)"/>
   


视图model类
    public class LoginPM
    {
        public var username : String="good";
        public var password : String="bad";
        public var isinit:Boolean=false;
       
        [init]
        public function LoginPM():void
        {
            isinit=true;
        }
       
        [MessageDispatcher]
        public var sendMessage:Function;
       
        public function setUsername( username : String ) : void
        {
            this.username = username;
        }
       
        public function setPassword( password : String ) : void
        {
            this.password = password;
        }
       
        public function login( username:String, password:String ):void {
           
            if( username != '' && password != '' ) {
                message = '';
                var loginMessage:LoginMessage = new LoginMessage( username, password );
                sendMessage( loginMessage );  //派发消息
            }
        }

        //接收登录处理结果,当Commandod类的方法result处理完成后,自动派发CommandResult命令
        [CommandResult(type="com.messages.LoginMessage")]
        public function handleResult() : void {
            if( session.loggedIn ) {
                mainPresentationModel.switchTo( Constants.STATE_DASHBOARD );
            }
            else {
                message = ResourceManager.getInstance().getString(
                    'General', 'loginFailed' );
            }
        }
        //当Commandod类的方法error处理完成后,自动派发CommandError命令
        [CommandError(type="com.messages.LoginMessage")]
        public function handleError():void {
            message = ResourceManager.getInstance().getString(
                'General', 'serviceFailed' );
        }

    }

4.Command包
    一个服务对应着一个Command类,比如CreateUserCommand,LoadUsersCommand。
例子代码:
public class LoginCommand {
        [Inject]
        public var loginService:IUserService;
       
        [Inject]
        public var session:Session;
       
        private static const logger:Logger = LogContext.getLogger( LoginCommand );
       
        public function execute( message:LoginMessage ):AsyncToken {
            return loginService.login( message.username, message.password );
        }
       
        public function result ( user:User ) : void {
            if( user != null ) {
                session.loggedIn = true;
                session.user = user;
            }
            else {
                session.loggedIn = false
            }
        }
       
        public function error (fault:Fault) : void {
            logger.error( "service call failed: " + fault.message );
        }
       
       
    }
在配置文件中必须设置动态命令标签:
   

5.Service包
    Service类负责与后台进行交互,从WEB服务器或数据库获取数据。
模拟后台调用代码如下:
    public class UserService implements IUserService {
        private var user:User;
        private var mockServiceUtil:MockServiceUtil = new MockServiceUtil;
       
        public function LoginServiceMock() {
            user = new User();
            user.id = "1";
            user.firstname = "Jochen";
            user.lastname = "Hilgers";
        }
       
        public function login(username:String, password:String):AsyncToken {
            return mockServiceUtil.createToken( user );
        }

6.Model包
    model类负责封装对象的属性,model类主要分为二种:一、实体对象,比如用户UserModel,班级BjModel等;二、传递的消息,比如登录事件中传递的LoginMessage。
例子:
    public class LoginMessage {
        public var username:String;
        public var password:String;
       
        public function LoginMessage( username:String, password:String ) {
            this.username = username;
            this.password = password;
        }
    }

    [RemoteClass(alias="com.model.User")]
    public class User {
       
        public var id:String;
        public var firstname:String;
        public var lastname:String;
    }







阅读(2904) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

chinaunix网友2011-01-23 16:26:36

你好,请问可以发我一份源码吗?谢谢啦, 我的邮箱地址:107602976@qq.com

chinaunix网友2010-06-09 00:01:31

你好,请问一下有源代码下载吗?可以发给我吗,谢谢。就这个示例的,我也正在看parsley相关的知识,有机会多向你请教一下。 邮箱 tsball@qq.com