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

PureMVC 在 Swing 應用中的實戰入門:架構解析與範例實作

     編輯:Java 相關知識

前言

PureMVC 是一個輕量級 MVC 框架,源自 Flex 社群,後移植至 Java、C#、Python 等多語言。其核心目標:將應用分離為低耦合的 Model、View、Controller 三層,透過單例 Facade 統一通訊。本文以 Swing 桌面應用為例,詳細解析 PureMVC 運作機制與實作要點。

PureMVC 核心架構

四大核心角色(皆為單例):

  • Facade:唯一對外介面,簡化開發複雜度
  • Model:管理資料與業務邏輯,透過 Proxy 封裝
  • View:管理 UI 元件,透過 Mediator 封裝
  • Controller:管理命令邏輯,透過 Command 封裝

核心流程:通知機制

// 發送通知的標準方法
public void sendNotification(String notificationName, Object body, String type);
// notificationName: 常量字串,如 "LOGIN_SUCCESS"
// body: 任意傳遞資料 (Map, VO, DTO 等)
// type: 可選標識

關鍵元件實作詳解

1. Facade 進入點與命令註冊

public class ApplicationFacade extends Facade {
    private static ApplicationFacade instance;

    protected ApplicationFacade() { super(); }

    public static ApplicationFacade getInstance() {
        if (instance == null) instance = new ApplicationFacade();
        return instance;
    }

    @Override
    protected void initializeController() {
        super.initializeController();
        // 註冊啟動命令
        registerCommand(ApplicationConstants.INIT_START, InitStartCommand.class);
    }

    public void startup() {
        sendNotification(ApplicationConstants.INIT_START, null, null);
    }
}

2. Command 處理業務邏輯

public class InitStartCommand extends SimpleCommand {
    @Override
    public void execute(INotification notification) {
        // 註冊後續所有業務命令
        registerCommand(ApplicationConstants.SHOW_FRAME_01, ShowFrameCommand.class);
        registerCommand(ApplicationConstants.SHOW_FRAME_02, ShowFrameCommand.class);
        registerCommand(ApplicationConstants.LOGIN, LoginCommand.class);
        // ... 其他命令
    }
}

public class ShowFrameCommand extends SimpleCommand {
    @Override
    public void execute(INotification notification) {
        String cmdName = notification.getName();
        if (ApplicationConstants.SHOW_FRAME_01.equals(cmdName)) {
            doShowFrame01();
        } else if (ApplicationConstants.SHOW_FRAME_02.equals(cmdName)) {
            doShowFrame02();
        }
    }
}

3. Mediator 處理 View 事件與通知

public class MainFrameMediator extends Mediator {
    public static final String NAME = "MainFrameMediator";
    private MainFrame mainFrame;

    public MainFrameMediator(MainFrame viewComponent) {
        super(NAME, viewComponent);
        mainFrame = (MainFrame) viewComponent;
        // 綁定 UI 事件發送通知
        mainFrame.getMenuFrame01().addActionListener(e -> 
            facade.sendNotification(ApplicationConstants.SHOW_FRAME_01));
    }

    @Override
    public String[] listNotificationInterests() {
        return new String[] {
            ApplicationConstants.LOGIN_SUCCESS,
            ApplicationConstants.CREATE_FRAME,
            ApplicationConstants.EXIT,
            ApplicationConstants.SEND_TO_FRAME_01,
            ApplicationConstants.SEND_TO_FRAME_02
        };
    }

    @Override
    public void handleNotification(INotification notification) {
        switch (notification.getName()) {
            case ApplicationConstants.LOGIN_SUCCESS:
                doLoginSuccess(notification);
                break;
            case ApplicationConstants.SEND_TO_FRAME_01:
                forwardToFrame01(notification);
                break;
            // ...
        }
    }
}

4. Proxy 管理資料 (Model 層)

public class UserProxy extends Proxy {
    public static final String NAME = "UserProxy";
    private UserVO userData;

    public UserProxy() { super(NAME); }

    public void setUserData(UserVO vo) { this.userData = vo; }
    public UserVO getUserData() { return userData; }
}

完整應用場景:登入 → 主視窗 → 內部視窗通訊

  1. 啟動:ApplicationFacade.getInstance().startup() 發送 INIT_START
  2. 登入:登入框發送 LOGIN → LoginCommand 驗證 → 發送 LOGIN_SUCCESS (攜帶用戶資料)
  3. 主視窗:MainFrameMediator 接收 LOGIN_SUCCESS 顯示主視窗
  4. 選單操作:點選選單發送 SHOW_FRAME_01/02 → Command 建立 JInternalFrame 並註冊對應 Mediator
  5. 跨視窗通訊:Frame01 發送 SEND_TO_FRAME_02 → Frame02 Mediator 與 MainFrame Mediator 同時接收處理

常量定義範例

public class ApplicationConstants {
    public static final String INIT_START = "initStart";
    public static final String LOGIN = "login";
    public static final String LOGIN_SUCCESS = "loginSuccess";
    public static final String SHOW_FRAME_01 = "showFrame01";
    public static final String SHOW_FRAME_02 = "showFrame02";
    public static final String SEND_TO_FRAME_01 = "sendToFrame01";
    public static final String SEND_TO_FRAME_02 = "sendToFrame02";
    public static final String CREATE_FRAME = "createFrame";
    public static final String EXIT = "exit";
}

PureMVC 在 Swing 中的優勢與注意事項

優勢

  • 嚴格分層:UI、業務、資料完全解耦
  • 可測試性:Command、Mediator、Proxy 皆可單元測試
  • 擴展性:新增功能只需註冊新 Command/Mediator,不修改既有代碼
  • 團隊協作:前後端、UI/邏輯可平行開發

注意事項

  • 記憶體洩漏風險:Mediator/Proxy 需在視窗關閉時移除 (facade.removeMediator(), facade.removeProxy())
  • 過度設計:小型專案可能不需要完整 PureMVC
  • 學習曲線:需理解觀察者模式、命令模式、單例模式
  • 執行緒安全:Swing 非執行緒安全,PureMVC 通知處理需確保在 EDT 執行 (SwingUtilities.invokeLater)

專案結構建議

src/
├── com.myapp/
│   ├── facade/           # ApplicationFacade
│   ├── controller/       # Commands
│   ├── model/            # Proxies, VOs
│   ├── view/             # Mediators, UI Components
│   ├── constants/        # ApplicationConstants
│   └── Main.java         # 程式入口
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved