我正在使用MVVM模式创建JavaFX桌面应用程序。每个View
需要一个ViewModel
。我决定不使用ViewA viewA = new ViewA(new ViewModelA());
,而是使用工厂模式对其进行抽象。
ViewFactory构造函数具有用于视图模型所需的其他服务的参数。例如,我的应用程序的一部分正在显示与CollectionsView
和CollectionsViewModel
相对应的数据库中存储的所有图像集合。为了从数据库中检索所有图像和集合,我创建了一个CollectionService
,并将其传递给ViewFactory。
代码:
public interface CollectionService {
List<ImageCollectionItem> getAllImagesForCollection(Collection collection);
List<Collection> getAllCollections();
}
public class CollectionsView extends View<CollectionsViewModel> {
public CollectionsView(CollectionsViewModel model) { ... }
}
public class CollectionsViewModel implements ViewModel {
public CollectionsViewModel(CollectionService collectionService) {
collections.set(collectionService.getAllCollections());
}
}
public class ViewFactory {
public ViewFactory(CollectionService collectionService) { ... }
public CollectionsView createCollectionsView() {
return new CollectionsView(new CollectionsViewModel(collectionService));
}
}
到目前为止,一切都很好。问题始于另一个View
ConnectView
,它基本上是一个数据库选择屏幕,其底部有一个连接按钮。按下连接按钮后,视图应变为主视图,为简单起见,假设为CollectionsView
。
稍微抽象一下,我用一种方法创建了一个ConnectionManager
接口(我知道名称不是最好的接口,但我想不出更好的接口。也许ConnectionNotifier
?)表示已建立与数据库的新连接,并已通过相应的SQL Connection
实例传递。
代码:
public class ConnectView { ... }
public class ConnectViewModel {
public ConnectViewModel(ConnectionManager connectionManager, ...)
public onConnectPress() {
// check database exists, valid schema, etc
// create connection
connectionManager.connected(newConnection);
}
}
public interface ConnectionManager {
void connected(Connection connection);
}
现在在实现ConnectionManager
时,调用connected
时,将实例化需要数据库的服务,并且屏幕上的视图变为CollectionsView
。
为此,我创建了一个名为NavigationService
的新类,该类使用ViewFactory
创建视图并将其设置为屏幕上的视图。
代码:
public class NavigationService {
public NavigationService(ViewFactory viewFactory, ...) { ... }
public void goToCollectionsView() {
CollectionsView colView = viewFactory.createCollectionsView();
// set colView on screen
}
}
ConnectionManager connectionManagerImpl = connection -> {
// create services that need connection (CollectionService, ...)
navigator.goToCollectionsView();
}
同样,一切正常。但是,如果我有不需要连接状态的附加View
怎么办?也许连接屏幕上的帮助按钮应该创建一个HelpView
?如何返回连接屏幕?要在导航器中添加goToConnectView()
,我必须将ConnectionManager
传递给它以创建视图,而视图又需要导航器。
因此,要创建ConnectionManager
,我需要NavigatorService
,反之亦然。
我考虑过的解决方案:
ConnectedStateNavigatorService
和NotConnectedStateNavigator
中拆分导航器,这又需要在ConnectedStateViewFactory
和NotConnectedStateViewFactory
中拆分视图工厂。我不喜欢选项1,因为我不想依赖额外的语句,看起来很脏。
我也不喜欢选项2,因为在我看来,这种带有侦听器,事件等的执行流程更适合C#,而不是Java的正确选择。同样,我必须依靠额外的addListener
调用。
虽然我不喜欢选项3,但这是我的选择。但同样,它感觉不对。我的代码开始变得杂乱无章,服务,工厂在我的应用程序中已将它们编码为接口,这意味着每个工厂都需要额外的类。
我的问题是:您认为可以吗?
注意:我不想使用mvvmFX框架,因为我不喜欢所有魔术,也不太依赖反射。
(抱歉我的英语,但我不是母语人士)