java引用不在范围内的对象

时间:2017-01-20 16:02:36

标签: java object scope

当我的java项目变大时总会弹出的一个问题是,是否有一种简单的方法可以引用超级或getParent()无法引用的特定对象。下图应说明我当前的问题: enter image description here

对于每个FileListItem,我想要实现一个需要ProtocolController方法的新FileListItemController。有没有办法在FileListItems中引用main实例化的ProtocolController对象,而不是通过mainWindow,FileListContentPanel,FileListItems传递它?

首先感谢你的所有答案。

我正在使用我的项目的模型,视图和控制模式。

单身人士模式听起来很有趣,但我的感觉是它并没有解决我的问题。这里有一些代码来说明我的问题:

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
    }
}

4 个答案:

答案 0 :(得分:0)

有不同的方法。

例如,如果您只需要一个ProtocolController实例,则可以使用singleton pattern。然后,每个FileListItemController都可以检索相同的ProtocolController对象。

class ProtocolController {

    private static instance;

    private ProtocolController() { }

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

然后,您可以从ProtocolController.getInstance()中获取FileListItemController,然后调用所需的方法。

答案 1 :(得分:0)

如果您只有一个FileListItemController 实例,则可以将Singleton pattern与“Lazy instantiation”结合使用。

并且ProtocolController像这样实例化FileListItemController

FileListItemController fileListItemControllerInstance = FileListItemController.getInstance();

修改

如果每个FileListItem引用一个FileListItemController ,您可以使用FactoryAbstract Factory Pattern

在这种情况下,您的ProtocolController可以启动FileListItemController工厂。如果需要,您可以将ProtocolController引用传递给工厂。

然后FileListItem可以使用此工厂创建新的FileListItemController个实例。

答案 2 :(得分:0)

这看起来像是模型 - 视图 - 控制器设计模式的用例。

您的FileListItem个对象是模型(您需要一个新类来保存它们)。 Controller和View(FileListControlPanel)都可以获得对Model的引用。然后,Controller使用模型上的方法来更改其内容,View会预订模型的事件以显示更改。

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

答案 3 :(得分:0)

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都不了解该协议。