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. //
4. private static ApplicationFacade instance = null;
5.
6. //启动的主程序实例
7. private PureMVC_Main main ;
8. /**
9. *
10. * @return
11. */
12. public static ApplicationFacade getInstance(){
13. if( instance == null) instance = new ApplicationFacade ();
14. return instance ;
15. }
16.
17. /**
18. *
19. */
20. protected void initializeController() {
21. "ApplicationFacade.initController()");
22. super.initializeController();
23. class);
24. }
25.
26. /**
27. *
28. * @param main
29. */
30. public void startup(PureMVC_Main _main) {
31. "ApplicationFacade.startup");
32. this.main = _main;
33. //发送通知(notification)给控制器 ,通知名称为 NotiName.NOTI_START(这个String是自己定义的)
34. //sendNotification是用来发送消息的函数 这是一个全局的函数 。
35. //三个参数为 String 通知名称
36. // Object 通知要传递的内容可以是任何对象
37. // String 一般默认为null
38. //这个通知会在 StartCommand.java中被处理。
39. this.sendNotification(NotiName.NOTI_START, null, null);
40. }
41. }
这样保证了静态变量facade只有一个实例instance
而这个getInstance 择有具体的main程序来调用,当调用时 框架就启动了。
同时在main程序启动框架时,需要同时调用startup方法,
startup方法做了这么几件事情
1.将main程序的引用传给了facade
2.注册了控制器startupCommand。
1. public class StartupCommand extends MacroCommand{
2. protected void initializeMacroCommand() {
3. "PrepStartUpCommand.initializeMacroCommand()");
4. class);
5. class);
6. class);
7. }
8. }
而startupCommand又注册了另外3个控制器,他们的作用分别是
注册代理:
1. public class PrepModelCommand extends SimpleCommand implements ICommand{
2.
3. public void execute(INotification noti){
4. "PrepModelCommand.execute()");
5. this.facade.registerProxy(new LoginProxy());
6. }
7. }
让Mediator得到页面的引用
1. public class PrepViewCommand extends SimpleCommand implements ICommand{
2.
3. public void execute(INotification noti){
4. "PrepViewCommand.execute("+ noti.getName() + ")");
5.
6. this.facade.registerMediator(new LoginMediator(new LoginWindow()));
7. }
8. }
还有一个 是保存Controller与Command的映射,注册消息 与Command 当Command需要时 Command会被创建。
1. public class PrepControllerCommand extends SimpleCommand implements ICommand{
2.
3. /**
4. * 这个方法一定会被执行。用来分析传过来的消息(Notification:PureMVC中各个模块传递的信息)
5. */
6. @Override
7. public void execute(INotification noti){
8. "PrepComtrollerCommand.excute()");
9. this.facade.registerCommand(NotiName.NOTI_LOGIN, LoginCommand.class);
10. }
11. }
这样框架就启动了。下面来说说登录的例子。
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.
8. @Override
9. public void handleNotification(INotification noti) {
10. if (noti.getName().equals(NotiName.LOGIN_SUCCESS)){
11. "login success");
12. }
13.
14. if (noti.getName().equals(NotiName.LOGIN_FAILED)){
15. "login failed " + noti.getBody().toString());
16. }
17. }
第一个方法罗列出 要接受的消息名字
第二个方法进行处理消息。
再看以下代码
1. public LoginMediator(LoginWindow v) {
2. super(NAME, null);
3. // TODO Auto-generated constructor stub
4. this.setViewComponent(v);
5. view = v;
6. true);
7.
8. new ActionListener(){
9. public void actionPerformed(ActionEvent e) {
10. // TODO Auto-generated method stub
11. login();
12. }
13. });
14. }
15.
16. private void login(){
17. //得到所有用户登录的信息 就是界面上输入的信息
18. new User(
19. view.txtName.getText(),
20. view.pwdPwd.getText()
21. );
22. //将这个信息发送给LoginCommand.java控制器。
23. //注意这个消息要在 prepControllerCommand.java中注册 建立Mediator到Command的映射关系
24. null);
25. }
在Mediator中 处理了所有UI中的事件 比如说为Button添加监听
并且收集数据 (收集 用户名和密码)封装到User中(自动以Object),然后发送消息给Command,把这些数据也发送出去。
此时由于刚才在PrepControllerCommand.java中注册了这个消息 对应的LoginCommand会被激活,处理这个消息。
1. public class LoginCommand extends SimpleCommand implements ICommand {
2.
3.
4. public void execute(INotification noti) {
5. //根据对应的消息名字处理相关逻辑 并且调用后台(比如数据库)
6. if (noti.getName().equals(NotiName.NOTI_LOGIN) == true) {
7. User user = (User)noti.getBody();
8.
9. new LoginProxy();
10.
11. if(checkLogin(user))
12. lp.login(user);
13. else
14. "User name should not be empty!",null);
15. }
16. }
17.
18. private boolean checkLogin(User u){
19. //username should not be empty
20. if(u.getUsername() == null )return false;
21.
22. return true;
23. }
24. }
这里处理这个消息买并且调用Model中的Proxy。Proxy负责进行数据操作,比如得到远程服务器的数据,或者与数据库进行交互。
处理完数据后 吧数据通过消息(Notification)发送给Mediator 整个流程就完成了。
1. public class LoginProxy extends Proxy{
2. public static final String NAME = "LoginProxy";
3.
4. public LoginProxy() {
5. super(NAME, null);
6. "LoginProxy.LoginProxy()");
7. }
8.
9. public void login(User user) {
10. // TODO Auto-generated method stub
11. //这里用来进行数据库操作 将User信息给数据库 ,并且返回信息。,返回方式 也是使用Notification
12. //这里发送的Notification在Mediator中(handleNotification方法)处理 。
13. //方便起见。,我这里就不写数据库操作了。
14.
15. if(user.getUsername().equals("young") )
16. "login success!",null);
17. else
18. "login error ,wrong username",null);
19. }
20.
21. }
Mediator在HandleNotification中处理Proxy发来的消息