当我的java项目变大时总会弹出的一个问题是,是否有一种简单的方法可以引用超级或getParent()无法引用的特定对象。下图应说明我当前的问题:
对于每个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
}
}
答案 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
,您可以使用Factory
(Abstract 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);
Window
或Panel
都不了解该协议。