簡體   English   中英

java引用不在范圍內的對象

[英]java referencing objects that are not in scope

當我的 Java 項目變大時,總是會出現一個問題是,是否有一種簡單的方法可以引用 super 或 getParent() 無法引用的特定對象。 下圖應該說明我當前的問題: 在此處輸入圖片說明

對於每個 FileListItem,我想創建一個新的 FileListItemController,它需要來自 ProtocolController 的方法。 除了通過 mainWindow、FileListContentPanel、FileListItems 傳遞它之外,有沒有辦法在 FileListItems 中引用由 main 實例化的 ProtocolController 對象?


首先感謝您的所有回答。

我正在為我的項目使用模型、視圖、控制模式。

單例模式聽起來很有趣,但我的感覺是它不能解決我的問題。 這是一些代碼來說明我的問題:

public class Main {
    public static void main(String [ ] args) {
        ProtocolController pc = new ProtocolController();
        mainWindow mw = new mainWindow();

    }
}
public class ProtocolController {
    File protocol;
    public ProtocolController(File protocol){
        this.protocol = protocol;
    }

    public void writeSomethingToProtocolFile(String something){
        // write something to th protcol file specified by the object
    }
}
public class mainWindow {
    public mainWindow(){
        FileListContentPanel flcp = new FileListContentPanel();
    }
}
public class FileListContentPanel {
    public FileListContentPanel(){
        int numListItems = 10;
        for (int i = 0; i < 10; i++) {
            FileListItem fli = new FileListItem();
            FileListItemController flic = new FileListItemController(fli);
        }
    }
}
public class FileListItemController {

    public FileListItemController(FileListItem fli){

    }
    public void addSomethingToProtocol(String something){
        // at this point I want to use a method from the ProtocolController class instantiated by the main method
    }
}

對此有不同的方法。

例如,如果您只需要一個ProtocolController實例,則可以使用單例模式 然后每個FileListItemController都能夠檢索相同的ProtocolController對象。

class ProtocolController {

    private static instance;

    private ProtocolController() { }

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

然后,您可以從FileListItemController獲取ProtocolController.getInstance() ,然后調用所需的方法。

如果您只有一個FileListItemController實例,您可以使用帶有“延遲實例化”的單例模式

並且ProtocolController像這樣實例化FileListItemController

FileListItemController fileListItemControllerInstance = FileListItemController.getInstance();

編輯

如果每個FileListItem引用一個FileListItemController ,則可以使用Factory抽象工廠模式

在這種情況下,您的ProtocolController可以啟動FileListItemController工廠。 如果需要,您可以將ProtocolController引用傳遞給工廠。

然后FileListItem可以使用這個工廠來創建新的FileListItemController實例。

這看起來像是模型-視圖-控制器設計模式的用例。

您的FileListItem對象是模型(您需要一個新類來保存它們)。 Controller 和 View ( FileListControlPanel ) 都獲得了對模型的引用。 Controller 然后使用模型上的方法來更改其內容,而 View 訂閱模型的事件以顯示更改。

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Window不需要了解協議。 事實上, Panel也不需要了解協議。

使用依賴注入。


控制板

由於Panel創建控制器,因此Panel將需要對Protocol的引用。 所以你需要將協議注入面板。

class Panel {
    public Panel(Protocol protocol) {
        for(...) {
            Item item = new Item();
            Controller controller = new Controller(item, protocol);
        }
    }
}

我不建議像這樣在構造函數中填充列表,但我保留它以便代碼熟悉。

窗戶

為了防止Window知道Protocol ,您應該注入面板。

class Window {
    public Window(Panel panel) {
        // ...
    }
}

更新main

通過這些新更改,您將與您的類型進行如下交互:

Protocol protocol = new Protocol();
Panel panel = new Panel(protocol);
Window window = new Window(panel);

現在Window不需要依賴Protocol


介紹工廠

我提到了Panel也不需要依賴於Protocol

使用協議的是Controller 面板僅引用協議,以便將其傳遞給新創建的控制器。 創建控制器需要該協議。

您可以引入一個工廠來處理控制器的創建。 工廠將參考協議:

class ControllerFactory {
    private Protocol protocol;

    public ControllerFactory(Protocol protocol) {
        this.protocol = protocol;
    }

    public Controller newController(Item item) {
        return new Controller(item, protocol);
    }
}

Panel現在將依賴於工廠而不是協議:

class Panel {
    public Panel(ControllerFactory factory) {
        factory = factory;

        for(...) {
            Item item = new Item();
            Controller controller = factory.newController(item);
        }
    }
}

您的新用法如下:

Protocol protocol = new Protocol();
ControllerFactory factory = new ControllerFactory(protocol);
Panel panel = new Panel(factory);
Window window = new Window(panel);

WindowPanel都不知道該協議。

暫無
暫無

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

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