在Java中实现适当的C#事件(非委托) [英] Implementing a proper C# event (not delegate) in java
问题描述
此 SO答案以及同一问题中的其他帖子中已经提到,可以使用接口实现C#委托或Java FuncationInterfaces.
As already mentioned in this SO answer and the other posts in the same question, C# delegates can be implemented using interfaces or Java FuncationInterfaces.
但是,我希望在Java中实现适当的事件模型,而不是委托模型.有关两者的区别的简要介绍,请参见此.尤其是第一条评论.
However I am looking to implement a proper event model and not a delegate model in Java. For a brief on the difference of the two, please see this. Especially the first comment.
以下是我到目前为止尝试过的内容:
Below is what I have tried so far:
Event.java
Event.java
public class Event {
public interface EventHandler{
void invoke();
}
private Set<EventHandler> mEventHandlers = new HashSet<>();
public void add(EventHandler eventHandler){
mEventHandlers.add(eventHandler);
}
public void remove(EventHandler eventHandler){
mEventHandlers.remove(eventHandler);
}
public void invoke(){
for(EventHandler eventHandler : mEventHandlers){
if(eventHandler!=null) {
eventHandler.invoke();
}
}
}
}
EventPubisher.java
EventPubisher.java
public class EventPublisher {
public Event ValueUpdatedEvent;
public void UpdateValue(){
ValueUpdatedEvent.invoke();
}
}
EventConsumer.java
EventConsumer.java
public class EventConsumer {
EventPublisher ep = new EventPublisher();
public EventConsumer(){
ep.ValueUpdatedEvent.add(this::ValueUpdatedEventHandler);
}
private void ValueUpdatedEventHandler(){
// do stuff
}
}
这种设计的问题是我也可以编写如下代码:
The problem with this design is that I can write code like below as well:
public class EventConsumer {
.....
private void abuse(){
ep.ValueUpdatedEvent.invoke();
}
}
这尤其是事件所限制的.该事件仅应从声明类中引发,而不应从外部引发.
And this is particularly what events restrict. The event should be raised only from the declaring class and not from outside.
推荐答案
如@Jon Skeet在评论中所述,更改以下代码符合我的要求:
As mentioned by @Jon Skeet in the comments, changing the code as below meets my requirement:
EventPubisher.java
EventPubisher.java
public class EventPublisher {
private final Event ValueUpdatedEvent = new Event();
public void addEventHandler(Event.EventHandler eventHandler){
ValueUpdatedEvent.add(eventHandler);
}
public void removeEventHandler(Event.EventHandler eventHandler){
ValueUpdatedEvent.remove(eventHandler);
}
public void UpdateValue(){
ValueUpdatedEvent.invoke();
}
}
EventConsumer.java
EventConsumer.java
public class EventConsumer {
.....
private void abuse(){
// ep.ValueUpdatedEvent.invoke(); //Compilation error
}
}
这篇关于在Java中实现适当的C#事件(非委托)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!