我不确定如何正确地提出这个问题,但是那可能已经是该问题的一部分了。我将开始解释我真正想要实现的目标,然后切换到一个更简单的模型来发布问题。
我想实现的目标
Web UI框架“ Vaadin”当前有两个活动版本:Vaadin Flow(> 10)和Vaadin 8 Framework。两者都具有相同(或相似)的组件。有一个Grid本身具有很多功能。 Vaadin Flow和Vaadin 8 Framework的网格相似但不相同。它们具有相似的功能,例如它们具有为网格获取数据的数据提供程序,具有列等。但是相关函数具有不同的名称或参数。
我想通过“同步”功能扩展Grid(两个版本),以便几个用户可以使用Grid,并且他们的更改可以立即与其他用户共享。我将结果称为“ SynchronizedGrid”,它本身就是(extends
)原始网格,因此可以像原始Grid一样使用它。
我的问题
现在,我想稍微抽象一下这个问题,并将其称为Vaadin 8 Framework网格G8
,即Vaadin Flow网格G10
。
当我想扩展G8
和G10
时,我需要有两个扩展类(又名“ SynchronizedGrid”),我现在将其称为SG8
(哪个extends G8
)和SG10
(哪个extends G10
)
如何精确地编写一次同步功能并将其用于SG8
和SG10
。我正在考虑可以在SG
和SG8
中使用的常见SG10
类。
我想拥有三个库,一个用于SG
,两个用于SG8
(取决于Vaadin Framework 8和SG库)和SG10
(取决于vaadin流和SG库),而在SG8中逻辑很少-和SG10库,并尽可能多地在SG库中。
我的方法
多重继承(SG8 extends SG extends G8
和SG10 extends SG extends G10
)不起作用,因为Java不支持多重继承。
接口(class SG8 extends G8 implements SG
和class SG10 extends G10 implements SG
)
可以使用默认实现。这样做的好处是,我将不得不在SG8
和SG10
中实现G8
和G10
之间不同的功能。缺点是我不能在构造函数级别上工作。此外,我不愿意在接口中以default
实现方式包含很多逻辑。
在SG
和SG8
中包含SG10
并使其调用SG
的功能:我认为这需要SG8
和SG10
中的很多逻辑(何时以及如何调用SG
)
我希望有一个更好的方法来解决我的问题。如有任何提示,我将不胜感激。
编辑
当前同步看起来像这样:
public class SynchronizedGrid<T extends Selectable> extends Grid<T>{
private Class<T> clazz;
public SynchronizedGrid(Class<T> clazz) {
super(clazz); //adding all attributes as columns (and some more stuff)
this.clazz = clazz;
... //styling, some other features
ListDataProvider<T> dataProvider = new ListDataProvider(getStaticListOfValues());
setDataProvider(dataProvider);
dataProvider.addFilter(bean -> !bean.isSelected());
addItemClickListener(clickEvent -> {
if (clickEvent.getMouseEventDetails().isDoubleClick()) {
registerWork(clickEvent.getItem());
}
});
}
@Override
public void attach() {
super.attach();
registerAsObserver();
}
@Override
public void detach() {
super.detach();
unregisterAsObserver();
}
public List<T> getStaticListOfValues(){
StaticListStore
.getInstance()
.get(clazz);
}
public void registerWork(T item){
item.setSelected(true);
ObserverStore
.getInstance()
.get(clazz)
.forEach(synchronizedGrid -> synchronizedGrid.reload());
}
public void reload(){
getUI().access(() -> getDataProvider.refreshAll());
}
StaticListStore
和ObserverStore
是分别包含Map<Class<? extends Selectable>,List<? extends Selectable>
和Map<Class<? extends Selectable>,List<Grid<? extends Selectable>>
的单例,其中键是Bean的类。Selectable
是SynchronizedGrid的所有bean需要实现的接口。它包含方法void setSelected(boolean b)
和boolean isSelected()
我试图尽可能简化代码,删除了一些部分(例如在Vaadin中处理“推送”(从另一个线程或UI更新一个UI),并在此类中包含了尽可能多的代码,以提供简短的示例。是Vaadin Framework 8版本。VaadinFlow版本在以下方面有所不同:
没有
attach()
和detach()
可以覆盖,但可以使用addAttachListener()
和addDetachListener()
不是
addClickListener()
和clickEvent.getMouseEventDetails().isDoubleClick()
,而是addDoubleClickListener()
所有Vaadin类(例如
Grid
和DataProvider
)都位于不同的程序包中我的问题不一定是关于vaadin的特定主题,而是如何在架构上做到这一点,例如如果有任何我可以使用的设计模式。
最佳答案
Vaadin 14是唯一的“活动”对象(其中15个在管道中),由于旧应用程序的LTS(即错误修正),该站点上仍列出了8个。
对于新项目或使用14的项目,它应仅为14。与版本10一样,Vaadin完全更改了基本工作流程,因此“流程”从10开始。
编辑:
如果您确实需要同时使用这两种解决方案,那么可以使用Adapters封装Grid(几乎无论如何都要使用SynchronizedGrid-idea进行封装),Adapters本身就是具有通用功能的类/接口的子类/实现。根据您的一般结构,适配器可以分别在具有匹配的Vaadin依赖项的项目中使用。如果使用通用网格并使用SynchronizedGrid-Superclass / Interface,则使用网格的代码将不必了解任何有关它们的信息。但是我看到了很大的痛苦,因为这将要求其他部分也包括在子项目中。布局不兼容。
关于java - 如何将相同的扩展名写入一个类的两个不同版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60448836/