浏览 1954 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-11
最后修改:2010-01-26
MVC 设计模式已经非常的成熟并在WEB Application的开发中广泛使用,apache的开源项目struts就是典型的例子。MVC的本质就是是逻辑和显示分开,通过控制器进行协调。通常我们会感到控制器比较的肥大,这个是个有争议的问题。MIDP的用户界面开发是比较简单的,只有那么20几个类。但是由于导航一般只能通过 Command来实现,所以界面增多的情况下,如果没有有效的组织那么程序写起来非常的乱,最致命的是这样的程序可读性差、扩展性差、可维护性差。 应用MVC解决这个问题的关键是提供一个桥梁作用的控制器,它通常要有一个MIDlet作为参数。例如 public UIController(PhoneBookMIDlet pbm) { this.phoneBookMIDlet = pbm; } 为了传递事件,你可以定义一个内部类,在里面定义事件的代号。这样用起来非常的方便例如 public static class EventID { private EventID() { } public static final byte EVENT_NEW_RECORD_SELECTED = 1; public static final byte EVENT_SAVE_RECORD = 2; public static final byte EVENT_NEWPHONE_BACK_MAINUI = 3; public static final byte EVENT_LISTPHONE_BACK_MAINUI = 4; public static final byte EVENT_SEARCHUI_BACK_MAINNUI = 5; public static final byte ADD_NEW_RECORD = 100; public static final byte SEARCH_RECORD = 101; public static final byte CLEAR_RECORD = 102; public static final byte LIST_RECORD = 103; public static final byte HELP = 104; }我们要在这个控制器内初始化各个界面类,这样我们才能根据不同的事件代号进行导航。 public void init(Model model) { this.display = Display.getDisplay(phoneBookMIDlet); this.model = model; indexFunctionUI = new IndexFunctionUI(this); infomationUI = new InfomationUI(); newPhoneUI = new NewPhoneUI(this); listPhoneUI = new ListPhoneUI(this); searchPhoneUI = new SearchPhoneUI(this); displayWelcome(); } public void setCurrent(Displayable disp) { display.setCurrent(disp); } public void setCurrent(Alert alert, Displayable disp) { display.setCurrent(alert, disp); }由于本文主要讲述如何实现导航,因此关于Model不做任何介绍。细心的话你也许可以看出来我这些代码是在完成一个电话簿的功能。在从Record Management System从入门到精通之四中我会介绍自己编写的电话本。在控制器类中最重要的就是接受事件然后进行导航,也就是显示不通的界面。因此它的事件处理的方法是这样的。 public void handleEvent( int eventID) { switch (eventID) { case EventID.ADD_NEW_RECORD: { display.setCurrent(newPhoneUI); break; } case EventID.LIST_RECORD: { display.setCurrent(listPhoneUI); break; } case EventID.SEARCH_RECORD: { display.setCurrent(searchPhoneUI); break; } case EventID.EVENT_NEWPHONE_BACK_MAINUI: { display.setCurrent(indexFunctionUI); break; } case EventID.EVENT_LISTPHONE_BACK_MAINUI: { display.setCurrent(indexFunctionUI); break; } case EventID.EVENT_SEARCHUI_BACK_MAINNUI: { display.setCurrent(indexFunctionUI); break; } default: break; } } public void handleEvent(int eventID, Object[] obj) { }这是个重载的方法,当有参数传递过来的时候我们调用后面的方法。 接下来我们看界面类,它们通常包括控制器类、界面的Item还有一些Command。 public NewPhoneUI(UIController uicontroller) { super(Title.add_record); this.uicontroller = uicontroller; nameField = new TextField(Title.name, null, 25, TextField.ANY); mobileField = new TextField(Title.mobile, null, 25, TextField.PHONENUMBER); choice = new ChoiceGroup(Title.choice, ChoiceGroup.MULTIPLE); phoneField = new TextField(Title.phone, null, 25, TextField.PHONENUMBER); emailField = new TextField(Title.email, null, 25, TextField.EMAILADDR); choice.append(Title.detail, null); this.append(nameField); this.append(mobileField); this.append(choice); this.addCommand(saveCommand); this.addCommand(backCommand); this.setCommandListener(this); this.setItemStateListener(this); }通常他们把控制器类作为参数传递给构造器,并在构造器内部注册监听器,绘制界面等。它们通过commandAction()方法来传递事件编号给控制器类去处理,例如 public void commandAction(Command arg0, Displayable arg1) { // TODO Auto-generated method stub if (arg0 == backCommand) { uicontroller .handleEvent(UIController.EventID.EVENT_NEWPHONE_BACK_MAINUI); } }这样就基本上完成了导航问题,扩展起来非常容易,添加一个界面类,然后在控制器类中初始化并添加适当的事件编号就可以了。 想起来,这种解决方法真是非常经典!! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |