[英]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.