Java 具有不同类型和数据的事件

Java 具有不同类型和数据的事件,java,oop,Java,Oop,我正在用Java编写一个库,它抛出一个不同类型的事件,并根据类型使用不同的数据 例如,以下是扩展的EventObject: 公共类FooEvent扩展了EventObject{ 私有最终int事件类型; 私有最终对象fooEventObject; 公共事件(int类型,对象obj){/*…*/} public int getEventType(){/*…*/} public int getEventObject(){/*…*/} } 下面是我的听众目前的样子: FooEventListener

我正在用Java编写一个库,它抛出一个不同类型的事件,并根据类型使用不同的数据

例如,以下是扩展的EventObject:

公共类FooEvent扩展了EventObject{
私有最终int事件类型;
私有最终对象fooEventObject;
公共事件(int类型,对象obj){/*…*/}
public int getEventType(){/*…*/}
public int getEventObject(){/*…*/}
}
下面是我的听众目前的样子:

FooEventListener=新的FooEventListener(){
@凌驾
公共无效onDataChange(FooEvent事件){
开关(event.getEventType()){
案例事件类型栏:
Bars bar=(Bars)event.getEventObject();
/*使用酒吧对象*/
打破
案例事件类型:
Goo-Goo=(Goo)event.getEventObject();
/*使用Goo对象*/
打破
/*等等*/
}
}
}

我想知道这是否是解决这个问题的正确方法(尽管我怀疑这是正确的,因为库的用户需要知道转换到什么类型),其中我有不同的事件类型和对象,我不想为每个对象创建不同的事件和侦听器

解决这个问题的更好方法是使用泛型

public class FooEvent<T> extends EventObject {
    private final T fooEventObject;

    public FooEvent(T obj){/*...*/}
    public T getEventObject() {/*...*/}
}


//usage
SomeType object = new SomeType();
new FooEvent<SomeType>(object);
公共类FooEvent扩展了EventObject{
私有最终fooEvent对象;
公共事件(T obj){/*…*/}
public T getEventObject(){/*…*/}
}
//用法
SomeType对象=新的SomeType();
新事件(对象);

解决这个问题的更好方法是使用泛型

public class FooEvent<T> extends EventObject {
    private final T fooEventObject;

    public FooEvent(T obj){/*...*/}
    public T getEventObject() {/*...*/}
}


//usage
SomeType object = new SomeType();
new FooEvent<SomeType>(object);
公共类FooEvent扩展了EventObject{
私有最终fooEvent对象;
公共事件(T obj){/*…*/}
public T getEventObject(){/*…*/}
}
//用法
SomeType对象=新的SomeType();
新事件(对象);

我认为这是一种方式,但不是最干净的方式。您应该创建一个抽象类

public abstract class AbstractEventType<T> extends EventObject {}
等等

如果您只想使用一种事件类型,那么您至少可以将代码移动到您的框架中来确定类型,并通过为每个类型创建一个处理程序方法来避免“业务”代码的污染,例如

public interface MyEventListener {
    public void onFooChange(EventType<Foo> eventType);
    public void onBarChange(EventType<Bar> eventType);
}
公共接口MyEventListener{
公共void onFooChange(EventType EventType);
公共无效onBarChange(EventType EventType);
}

我认为这是一种方式,但不是最干净的方式。您应该创建一个抽象类

public abstract class AbstractEventType<T> extends EventObject {}
等等

如果您只想使用一种事件类型,那么您至少可以将代码移动到您的框架中来确定类型,并通过为每个类型创建一个处理程序方法来避免“业务”代码的污染,例如

public interface MyEventListener {
    public void onFooChange(EventType<Foo> eventType);
    public void onBarChange(EventType<Bar> eventType);
}
公共接口MyEventListener{
公共void onFooChange(EventType EventType);
公共无效onBarChange(EventType EventType);
}
番石榴提供了一种稍微不同的方法,可以处理多种事件类型

不幸的是,没有一个简单的解决方案可以使用不同类型的类型安全事件系统。对于每种类型的事件,您必须有一个侦听器/发布实现。您需要向一方传授所有存在的事件类型

有一种方法可以消除对
instanceof
开关(类型)
和强制转换的需要:

该模式使用事件对象知道自己的类型这一事实,这意味着它们可以调用正确的方法。缺点是您需要一个包含所有类型的侦听器接口

public class Test {

    abstract static class EventObject {
        protected abstract void deliver(EventListener listener);
    }

    static class AEvent extends EventObject {
        @Override
        protected void deliver(EventListener listener) {
            listener.onAEvent(this);
        }
    }

    static class BEvent extends EventObject {
        @Override
        protected void deliver(EventListener listener) {
            listener.onBEvent(this);
        }

    }

    interface EventListener {
        void onAEvent(AEvent event);

        void onBEvent(BEvent event);
        // ...
    }

    private static final EventListener LISTENER = new EventListener() {
        @Override
        public void onBEvent(BEvent event) {
            System.out.println("Got B Event! " + event);
        }

        @Override
        public void onAEvent(AEvent event) {
            System.out.println("Got A Event! " + event);
        }
    };

    private static void notifyListeners(EventObject event) {
        event.deliver(LISTENER);
    }

    public static void main(String[] args) {
        notifyListeners(new AEvent());
        notifyListeners(new BEvent());
    }

}
Guava提供了一种稍微不同的方法,可以处理多种事件类型

不幸的是,没有一个简单的解决方案可以使用不同类型的类型安全事件系统。对于每种类型的事件,您必须有一个侦听器/发布实现。您需要向一方传授所有存在的事件类型

有一种方法可以消除对
instanceof
开关(类型)
和强制转换的需要:

该模式使用事件对象知道自己的类型这一事实,这意味着它们可以调用正确的方法。缺点是您需要一个包含所有类型的侦听器接口

public class Test {

    abstract static class EventObject {
        protected abstract void deliver(EventListener listener);
    }

    static class AEvent extends EventObject {
        @Override
        protected void deliver(EventListener listener) {
            listener.onAEvent(this);
        }
    }

    static class BEvent extends EventObject {
        @Override
        protected void deliver(EventListener listener) {
            listener.onBEvent(this);
        }

    }

    interface EventListener {
        void onAEvent(AEvent event);

        void onBEvent(BEvent event);
        // ...
    }

    private static final EventListener LISTENER = new EventListener() {
        @Override
        public void onBEvent(BEvent event) {
            System.out.println("Got B Event! " + event);
        }

        @Override
        public void onAEvent(AEvent event) {
            System.out.println("Got A Event! " + event);
        }
    };

    private static void notifyListeners(EventObject event) {
        event.deliver(LISTENER);
    }

    public static void main(String[] args) {
        notifyListeners(new AEvent());
        notifyListeners(new BEvent());
    }

}

无论如何,这不是正确的方法,如果他可以使用合同(接口)而不是具体的实现,那就是正确的方法!我认为,如果你有不同的事件类型,你将处理不同的事件。也许他们很相似,但仍然不同编辑——或者巴特在下面给出的答案就是你一直在寻找的东西。无论如何,这不是正确的方法,如果他可以使用合同(接口)而不是具体的实现,那就是正确的方法!我认为,如果你有不同的事件类型,你将处理不同的事件。也许他们很相似,但仍然不同编辑——或者Bart在下面给出的答案就是你想要的。除了在这种情况下,当我创建侦听器时,我必须像这样声明覆盖:
public void onDataChange(FooEvent事件)
public void onDataChange(FooEvent事件)
或其他任何对象。除了这种情况,当我创建侦听器时,我必须像这样声明覆盖:
public void onDataChange(FooEvent事件)
public void onDataChange(FooEvent事件)
或任何其他对象;我知道这是一个解决方案,但它需要为每个事件(以及未来的事件)提供一个新的事件/侦听器接口,我希望有一个更有效的解决方案。好的,我知道,但在我看来,这仍然是最干净的方法。你应该让“丑陋”的代码远离生产代码。我认为这是一个设计的问题,以及yoz想用这个设计实现什么。如果您只有2或3个不同的EventType,那么让API的用户检查正确的类型是没有问题的。基斯,简单点@克里斯蒂安查克同意了。我更新了我的an