我用Java实现了一个不可变的系统.几乎每个班级都是不可改变的,并且它比我预期的要好得多.
我的问题是尝试发送事件.通常,您有一个事件源和一个事件监听器.源只是保存对侦听器的引用,并在事件发生时发送事件.
但是对于不可变,当您修改字段并创建新对象时,事件侦听器引用会发生更改.所以事件源发送到一些垃圾收集的旧引用.
因此,我的所有GUI类都是可变的,因为它们自然会使用很多事件.但我想找到一种处理事件的优雅方式,这样我就可以使这些事件变得不可变.
编辑:请求的示例代码:
public final class ImmutableButton {
public final String text;
public ImmutableButton(String text) {
this.text = text;
}
protected void onClick() {
// notify listeners somehow,hoping they haven't changed
}
}
public final class ImmutableWindow {
public final ImmutableButton button;
public ImmutableWindow(ImmutableButton button) {
this.button = button;
}
protected void listenForButtonClick() {
// somehow register with button and receive events,despite this object
// being entirely recreated whenever a field changes
}
}
虽然缺点是,如果您真的希望GUI对象是不可变的,您可以创建一个全局事件总线来解决侦听器附件问题.通过这种方式,您无需担心将注册事件侦听器的对象实例.事件总线将负责调度事件,监听器注册以及维护它们之间的映射.
这是一个简单的事件总线的草图设计.
public class EventBus {
private MapetorDefault(event,new ArrayList<>());
listeners.add(listener);
}
public void fireEvent(Event event,Object... args) {
List
编辑
监听器是处理程序 – 它们应该执行业务逻辑而不是保持状态.此外,它们不应该附加到组件.在上面的代码中,侦听器代码必须与ImmutableWindow分离 – 两者都应该独立存在.必须在应用程序启动期间的某处配置ImmutableWindow和ImmutableButton之间的交互(在事件总线中).
您还应该有一个UI组件的中央注册表,它可以通过唯一的ID进行标识,并使用此注册表查找(遍历组件树)组件的最新实例并进行交互.
在实践中,这样的事情……
// The main class. Do the wirings here.
public class App {
@Inject
private EventBus eventBus;
@postconstruct
public void init() {
ImmutableWindow window = new ImmutableWindow ();
ImmutableButton addButton = new ImmutableButton ();
eventBus.registerEventListener(Events.ADD_BUTTON_CLICKED,new AddButtonClickListener());
}
}
public class AddButtonClickListener implements EventListener {
@Inject
private SomeOtherService someOtherSvc;
@Inject
private UiRegistry uiRegistry;
public void handleEvent(Object... args) {
ImmutableButton addButton = args[0].getSource; // The newset instance of the button must be packed and delivered to the eventlistners when firing an event
ImmutableWindow targetwindow = uiRegistry.lookUp("identifier_of_the_window",ImmutableWindow.class);
// Perform interaction between the two components;
}
}
现在,您拥有完全分离的UI和业务逻辑.您可以随意重新创建组件,监听器不会受到影响,因为它们未附加到任何组件.
原文地址:https://www.jb51.cc/java/437446.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。