[英]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);
Window
或Panel
都不知道該協議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.