转自:http://blog.csdn.net/sutaizi/article/details/6588004

pureMVC 是一个轻量级的框架 它在 flex中非常流行(和cairngorm差不多火)

目前几乎已经移植到所有平台上。

下面实现java版得pureMVC搭建

先给大家看总体的层次:

众所周知 pureMVC是一个轻量级的MVC框架 分为 Model ,View ,Controller。这三个是pureMVC的核心。

除此之外pureMVC中含有一个单例模式Facade。facade负责与Model,View,Controller通信。这样就简化了开发的复杂度。

所以首先需要编写单一模式类facade 也就是上图的 ApplicationFacade.java

  1. public class ApplicationFacade extends Facade {
  2. //
  3. private static ApplicationFacade instance = null;
  4. //启动的主程序实例
  5. private PureMVC_Main main ;
  6. /**
  7. *
  8. * @return
  9. */
  10. public static ApplicationFacade getInstance(){
  11. if( instance == null) instance = new ApplicationFacade ();
  12. return instance ;
  13. }
  14. /**
  15. *
  16. */
  17. protected void initializeController() {
  18. trace.d("ApplicationFacade.initController()");
  19. super.initializeController();
  20. registerCommand(NotiName.NOTI_START, StartupCommand.class);
  21. }
  22. /**
  23. *
  24. * @param main
  25. */
  26. public void startup(PureMVC_Main _main) {
  27. trace.d("ApplicationFacade.startup");
  28. this.main = _main;
  29. //发送通知(notification)给控制器 ,通知名称为 NotiName.NOTI_START(这个String是自己定义的)
  30. //sendNotification是用来发送消息的函数 这是一个全局的函数 。
  31. //三个参数为 String 通知名称
  32. //          Object 通知要传递的内容可以是任何对象
  33. //          String 一般默认为null
  34. //这个通知会在 StartCommand.java中被处理。
  35. this.sendNotification(NotiName.NOTI_START, null, null);
  36. }
  37. }

这样保证了静态变量facade只有一个实例instance

而这个getInstance 择有具体的main程序来调用,当调用时 框架就启动了。

同时在main程序启动框架时,需要同时调用startup方法,

startup方法做了这么几件事情

1.将main程序的引用传给了facade

2.注册了控制器startupCommand。

  1. public class StartupCommand extends MacroCommand{
  2. protected void initializeMacroCommand() {
  3. trace.d("PrepStartUpCommand.initializeMacroCommand()");
  4. addSubCommand(PrepModelCommand.class);
  5. addSubCommand(PrepControllerCommand.class);
  6. addSubCommand(PrepViewCommand.class);
  7. }
  8. }

而startupCommand又注册了另外3个控制器,他们的作用分别是

注册代理:

  1. public class PrepModelCommand extends SimpleCommand implements ICommand{
  2. public void execute(INotification noti){
  3. trace.d("PrepModelCommand.execute()");
  4. this.facade.registerProxy(new LoginProxy());
  5. }
  6. }

让Mediator得到页面的引用

  1. public class PrepViewCommand extends SimpleCommand implements ICommand{
  2. public void execute(INotification noti){
  3. trace.d("PrepViewCommand.execute("+ noti.getName() + ")");
  4. this.facade.registerMediator(new LoginMediator(new LoginWindow()));
  5. }
  6. }

还有一个 是保存Controller与Command的映射,注册消息 与Command 当Command需要时 Command会被创建。

  1. public class PrepControllerCommand extends SimpleCommand implements ICommand{
  2. /**
  3. * 这个方法一定会被执行。用来分析传过来的消息(Notification:PureMVC中各个模块传递的信息)
  4. */
  5. @Override
  6. public void execute(INotification noti){
  7. trace.d("PrepComtrollerCommand.excute()");
  8. this.facade.registerCommand(NotiName.NOTI_LOGIN, LoginCommand.class);
  9. }
  10. }

这样框架就启动了。下面来说说登录的例子。

PureMVC 的View分为2个部分 一个是 纯的UI界面,另一个是Mediator模式

这种模式的好处在于他将UI界面(如loginWondow.java--登录界面)中所有的UI组件 比如 button textField ..封装在一起,通过保存UI界面的应用来调用他们。

打个比方就是:

一栋宿舍楼 ,每一间宿舍都是一个UI控件,真个宿舍楼就是一个Mediator,宿舍楼门口有看门的大爷,大爷知道所有宿舍的情况,。

当有人访问宿舍们需要知道具体某间宿舍的情况的时候 他只需要去问门卫大爷。不需要亲自走到那间宿舍。就能知道具体情况。

在Mediator中有2个重要方法:

  1. public String[] listNotificationInterests() {
  2. String[] list = {
  3. NotiName.LOGIN_SUCCESS, NotiName.LOGIN_FAILED
  4. };
  5. return list;
  6. }
  7. @Override
  8. public void handleNotification(INotification noti) {
  9. if (noti.getName().equals(NotiName.LOGIN_SUCCESS)){
  10. trace.d("login success");
  11. }
  12. if (noti.getName().equals(NotiName.LOGIN_FAILED)){
  13. trace.d("login failed " + noti.getBody().toString());
  14. }
  15. }

第一个方法罗列出 要接受的消息名字

第二个方法进行处理消息。

再看以下代码

  1. public LoginMediator(LoginWindow v) {
  2. super(NAME, null);
  3. // TODO Auto-generated constructor stub
  4. this.setViewComponent(v);
  5. view = v;
  6. v.setVisible(true);
  7. v.btnLogin.addActionListener(new ActionListener(){
  8. public void actionPerformed(ActionEvent e) {
  9. // TODO Auto-generated method stub
  10. login();
  11. }
  12. });
  13. }
  14. private void login(){
  15. //得到所有用户登录的信息 就是界面上输入的信息
  16. User user = new User(
  17. view.txtName.getText(),
  18. view.pwdPwd.getText()
  19. );
  20. //将这个信息发送给LoginCommand.java控制器。
  21. //注意这个消息要在 prepControllerCommand.java中注册 建立Mediator到Command的映射关系
  22. sendNotification(NotiName.NOTI_LOGIN,user,null);
  23. }

在Mediator中 处理了所有UI中的事件  比如说为Button添加监听

并且收集数据 (收集 用户名和密码)封装到User中(自动以Object),然后发送消息给Command,把这些数据也发送出去。

此时由于刚才在PrepControllerCommand.java中注册了这个消息 对应的LoginCommand会被激活,处理这个消息。

  1. public class LoginCommand extends SimpleCommand implements ICommand {
  2. public void execute(INotification noti) {
  3. //根据对应的消息名字处理相关逻辑 并且调用后台(比如数据库)
  4. if (noti.getName().equals(NotiName.NOTI_LOGIN) == true) {
  5. User user = (User)noti.getBody();
  6. LoginProxy lp = new LoginProxy();
  7. if(checkLogin(user))
  8. lp.login(user);
  9. else
  10. sendNotification((String) NotiName.LOGIN_FAILED,"User name should not be empty!",null);
  11. }
  12. }
  13. private boolean checkLogin(User u){
  14. //username should not be empty
  15. if(u.getUsername() == null )return false;
  16. return true;
  17. }
  18. }

这里处理这个消息买并且调用Model中的Proxy。Proxy负责进行数据操作,比如得到远程服务器的数据,或者与数据库进行交互。

处理完数据后 吧数据通过消息(Notification)发送给Mediator 整个流程就完成了。

  1. public class LoginProxy extends Proxy{
  2. public static final String NAME = "LoginProxy";
  3. public LoginProxy() {
  4. super(NAME, null);
  5. trace.d("LoginProxy.LoginProxy()");
  6. }
  7. public void login(User user) {
  8. // TODO Auto-generated method stub
  9. //这里用来进行数据库操作 将User信息给数据库 ,并且返回信息。,返回方式 也是使用Notification
  10. //这里发送的Notification在Mediator中(handleNotification方法)处理 。
  11. //方便起见。,我这里就不写数据库操作了。
  12. if(user.getUsername().equals("young") )
  13. sendNotification(NotiName.LOGIN_SUCCESS,"login success!",null);
  14. else
  15. sendNotification(NotiName.LOGIN_FAILED,"login error ,wrong username",null);
  16. }
  17. }

Mediator在HandleNotification中处理Proxy发来的消息

最新文章

  1. Windows下用tree命令生成目录树
  2. LeetCode126:Word Ladder
  3. Educational Codeforces Round 16---部分题解
  4. 写的cursor demo仅作记录
  5. artice与section的区别
  6. 使用switch case语句来显示月份的对应天数
  7. Labeling Balls
  8. hdoj 1175 (bfs)
  9. IDEA使用心得-----懒得截图了,但是大家应该看得懂
  10. PHP获取文件扩展名的五种方式
  11. 【Hibernate】Unable to locate appropriate constructor on class原因分析
  12. luogu 2569 股票交易 单调队列dp
  13. IDEA git修改远程仓库地址
  14. android 常见内存泄漏原因及解决办法
  15. 观察者模式与Guava EventBus
  16. ps抠图
  17. javac的访问者模式2
  18. linux下安装apache与php
  19. 【刷题】BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
  20. 行列式(二):余子式&代数余子式

热门文章

  1. php curl 抓取内容
  2. C#使用LitJson解析JSON(转)
  3. Asp.net MVC 单元测试 简要笔记
  4. oracle 字段类型详解
  5. Linux服务器建站基础-选择何种配置和安装环境项目
  6. BBED跳过归档
  7. HDU 1248 寒冰王座
  8. 辽宁OI2016夏令营模拟T2-road
  9. jQuery复习:第四章
  10. 【Sort】希尔排序