繁体   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