簡體   English   中英

Java:我應該在哪里放置匿名監聽器邏輯代碼?

[英]Java: where should I put anonymous listener logic code?

我們在工作中討論了在java中使用監聽器的最佳實踐:監聽器邏輯是應該保留在匿名類中,還是應該在單獨的方法中,例如:

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // code here
    }
});

要么

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        buttonPressed();
    }
});

private void buttonPressed() {
    // code here
}

這是可讀性和可維護性方面的推薦方法? 我更喜歡將代碼保留在偵聽器中,並且只有當它變得太大時才使其成為內部類。 在這里,我假設代碼不會在其他任何地方重復。

謝謝。

我的自我規則是:

  1. 如果偵聽器有兩個以上的方法,請創建一個命名類。
  2. 如果偵聽器跨越10行以上,則創建一個命名類。

非常簡單,易於遵循並產生或多或少的可讀代碼。 但后來我不得不承認我從未想過你的例子所展示的內容。

這個問題在這里部分回答:

是否有更好的聽眾練習

我也不喜歡Anonymous方式有兩個原因:
1)你不能輕易地重復使用代碼,所以你可能會發現你有一段時間后重復代碼2)我發現它打破了代碼的閱讀(其他人不同意......個人品味)。 我想每個人都會同意,如果你做的超過5-10行,那么一個匿名的內部課程不是一個好主意(我會說超過2個是太多了)。

在我個人看來,“這取決於”。 如果只將偵聽器添加到單個組件中,非常簡單並且是GUI的組成部分,那么匿名內部類就可以正常工作。 如果監聽器很復雜,會被添加到多個組件中,會有自己獨立的狀態,那么單獨一個獨立的類就更好了。 中間是私人內部階級。 HTH。

編輯:我的壞。 我正在回答一個不同的問題 - 是否為聽眾使用單獨的獨立課程。 至於是否將內部內部代碼保持在內聯類代碼與方法中,我同意另一張海報,它將取決於偵聽器代碼的大小和復雜性。

如果需要從匿名內部類以外的任何東西訪問方法buttonPressed() ,那么使用方法。 否則只需將代碼放在actionPerformed()

根據我的個人經驗,最好遵循MVC模式。 這種方式有一個單獨的類代表一個模型,它創建所有相關的動作,動作監聽器等。最好將動作表示為最終的類字段,它們在構造函數中實例化。

例如:

public class Model {
    private final Action buttonAction;
    ...

    public Model(final IController controller) {
       buttonAction = createButtonAction(controller);
       ...
    }

    private Action createButtonAction(final IController controller) {
        Action action = new Action("Action") {
            public void actionPerformed(final ActionEvent e) {
                // do the required action with long running ones on a separate Thread
                controller.run();
            }
        };
        action.set...// other initialisation such as icon etc
        ...
        return action;
    }
    ...

    public Action getButtonAction() {
        return buttonAction;
    }
}

該視圖也由一個單獨的類表示,該類將模型作為其構造函數參數,其中實際的按鈕實例化發生。 例如:

public class View extends JPanel {
    public View(final Model model) {
       ...
       JButton button = new JButton(model.getButtonAction();
       ...
    }
}

使用這種方法,將actionPerformed的邏輯作為匿名類的一部分實現是非常方便的,因為它幾乎沒有被重用。 所有邏輯都封裝在控制器中,因此操作實際上充當控制器調用的包裝器,用作按鈕的模型。

是的,這在很大程度上取決於你要做的事情。 我認為,由於兩個神話,匿名內部階級已經得到了糟糕的說唱。 一個是無法重用匿名代碼。 二,內存泄漏。 但這些很容易通過簡單的方法解決。 保存對實例的引用。 對於共享代碼,只需創建對匿名內部類的引用。

Action action = new AbstractAction("Open") {...};
JButton button = new JButton( action );
JMenuItem menuItem = new JMenuItem( action );
panel.getActionMap().put("openFile", action );

現在,您可以跨多個組件重用該操作。 對於后來的內存泄漏問題,您可以使用該引用取消注冊它,或者第二個更簡單的選項是WeakListeners。 WeakListeners的優點是不需要在創建之后進行管理。

至於樣式,我發現Anonymous監聽器非常方便,在某些情況下,在Swing中處理線程時更容易閱讀,因為它將代碼保存在一個方法中(invokeLater,executeInBackground等)。 當你的匿名監聽器委托給一個實例方法時,我認為它將代碼分開,你無法在一個屏幕中讀取監聽器之前發生的事情和與監聽器相關的邏輯。 他們往往會分開,而且更難以遵循。

需要注意的是,如果使用ActionMaps,大多數內存泄漏都會隨着鍵盤監聽而消失。 不幸的是,像中央系統注冊的焦點聽眾或聽眾這樣的東西仍然是個問題。 (再次WeakListeners在這里很棒)。 並且您已經有了一個位置來保持每個組件的操作,因此無需創建額外的實例變量來保存它。 如果需要重用兩個組件(例如在菜單欄和控件中),請創建一個單獨的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM