首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME MIDlet 導航難題破解:應用 MVC 設計模式實現界面解耦

     編輯:J2ME

痛點:界面爆炸帶來的維護地獄

MIDP UI 僅有 20 幾個類,看似簡單,但當界面超過 7-8 個時,若將導航邏輯分散在各 CommandListener 中,代碼會迅速變成「義大利麵條」:可讀性差、擴展性差、可維護性差。本文展示如何引入 MVC 模式,建立集中式導航控制器,徹底解耦界面與業務邏輯。

架構設計:三層分離

層級職責典型類別
Model資料與業務邏輯(電話簿記錄、RMS 存取)PhoneBookModel
View界面呈現與使用者互動IndexFunctionUI、NewPhoneUI、ListPhoneUI…
Controller導航協調、事件分發、界面切換UIController

核心實現:UIController 詳解

1. 建構子持有 MIDlet 參考

public class UIController {
    private PhoneBookMIDlet phoneBookMIDlet;
    private Display display;
    private Model model;
    // 各界面實例
    private IndexFunctionUI indexFunctionUI;
    private NewPhoneUI newPhoneUI;
    // ...

    public UIController(PhoneBookMIDlet pbm) {
        this.phoneBookMIDlet = pbm;
    }
}

2. 事件代碼常量內部類(類型安全、易維護)


public static class EventID {
    private EventID() {}
    // UI 導航事件
    public static final byte EVENT_NEWPHONE_BACK_MAINUI = 3;
    public static final byte EVENT_LISTPHONE_BACK_MAINUI = 4;
    // 功能指令事件
    public static final byte ADD_NEW_RECORD = 100;
    public static final byte LIST_RECORD = 103;
    // ...
}

3. 界面初始化與顯示委派


public void init(Model model) {
    this.model = model;
    this.display = Display.getDisplay(phoneBookMIDlet);
    indexFunctionUI = new IndexFunctionUI(this);
    newPhoneUI = new NewPhoneUI(this);
    listPhoneUI = new ListPhoneUI(this);
    searchPhoneUI = new SearchPhoneUI(this);
    displayWelcome(); // 啟動畫面
}

public void setCurrent(Displayable disp) {
    display.setCurrent(disp);
}

4. 核心導航邏輯:集中式事件處理


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:
        case EventID.EVENT_LISTPHONE_BACK_MAINUI:
        case EventID.EVENT_SEARCHUI_BACK_MAINNUI:
            display.setCurrent(indexFunctionUI);
            break;
        default:
            break;
    }
}

// 重載:攜帶參數的事件(如搜尋關鍵字、編輯資料)
public void handleEvent(int eventID, Object[] obj) {
    // 擴展點
}

View 層:界面類與控制器交互


public class NewPhoneUI extends Form implements CommandListener {
    private UIController uiController;
    private Command saveCommand, backCommand;

    public NewPhoneUI(UIController controller) {
        super("新增聯絡人");
        this.uiController = controller;
        // 初始化輸入欄位、Command
        this.addCommand(saveCommand);
        this.addCommand(backCommand);
        this.setCommandListener(this);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == backCommand) {
            // 僅通知控制器事件代碼,不關心具體跳轉邏輯
            uiController.handleEvent(UIController.EventID.EVENT_NEWPHONE_BACK_MAINUI);
        } else if (c == saveCommand) {
            // 收集資料,交由 Model 處理,再通知控制器
            uiController.handleEvent(UIController.EventID.EVENT_SAVE_RECORD, new Object[]{name, phone});
        }
    }
}

擴展性展示:新增「群組管理」界面只需三步

  1. 建立 GroupManageUI 類,建構子接受 UIController
  2. 在 UIController.init() 中實例化並保存引用
  3. 在 EventID 增加 MANAGE_GROUPS,在 handleEvent() 添加 case 分支

零修改既有界面代碼,符合開放封閉原則。

總結:MVC 在 J2ME 中的價值

  • 導航集中化:所有跳轉邏輯在 UIController,一目了然
  • 界面復用:View 類不持有具體跳轉目標,可在不同流程中復用
  • 測試友好:Controller 可獨立單元測試,模擬事件驗證跳轉
  • 團隊協作:UI 設計師專注 View,邏輯工程師專注 Controller/Model

「想起來,這種解決方法真是非常經典!!」—— 原作者感嘆。是的,經典之所以經典,是因為它解決了本質複雜度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved