具有泛型的订阅模型 - 实现多个通用接口

时间:2014-03-29 15:11:52

标签: java generics design-patterns subscription

所以我尝试用泛型制作一个订阅模型..看起来不错,但现在我遇到了一些问题。

接收机

public interface Receiver<E> {
    public void receive(E event);
}

订阅注册表

public class ClientRegistry<T> {
    private Set<Receiver<T>> clients = new HashSet<Receiver<T>>();

    public void subscribe(Receiver<T> client) {
        clients.add(client);
    }

    public void unsubscribe(Receiver<T> client) {
        clients.remove(client);
    }

    public void broadcast(T eventObject) {
        for(Receiver<T> client: clients) {
            client.receive(eventObject);
        }       
    }   
}

到目前为止听起来不错,嗯?

现在出现了问题:

public class Screen implements Receiver<KeyEvent>, Receiver<MouseMoveEvent> {
    @Override
    public void receive(KeyEvent event)
    {
        // work
    }

    @Override
    public void receive(MouseMoveEvent event)
    {
        // work
    }
}

现在这是无效的语法:

The interface Receiver cannot be implemented more than once
with different arguments: Receiver<MouseMoveEvent> and Receiver<KeyEvent>

如何更改我的系统以使其尽可能通用,但要使其正常工作?

2 个答案:

答案 0 :(得分:2)

不要让Screen类本身实现两个Receiver接口。相反,使用组合:

public class Screen {
    private Receiver<KeyEvent> keyReceiver = new Receiver<KeyEvent>() {
        ...
    };

    private Receiver<MouseEvent> mouseReceiver = new Receiver<MouseEvent>() {
        ...
    };
}

答案 1 :(得分:1)

我会颠倒顺序,并使用Visitor Pattern

import java.util.*;

interface Event{
    void receive(Receiver receiver);    
}

class KeyEvent implements Event{
    @Override
    public void receive(Receiver receiver){
        receiver.receive(this);
    }   
}

class MouseEvent implements Event {
    @Override
    public void receive(Receiver receiver){
        receiver.receive(this);
    }   
}

interface Receiver {
    void receive(KeyEvent event);
    void receive(MouseEvent event);
}

class ClientRegistry {
    private Set<Receiver> clients = new HashSet<Receiver>();

    public void subscribe(Receiver client) {
        clients.add(client);
    }

    public void unsubscribe(Receiver client) {
        clients.remove(client);
    }

    public void broadcast(Event eventObject) {
        for(Receiver client: clients) {
            eventObject.receive(client);
        }       
    }   
}

public class Screen implements Receiver {

    public void receive(KeyEvent event) {
        //work
        System.out.println("Processing key event");
    }
    public void receive(MouseEvent event) {
        //work
        System.out.println("Processing mouse event");
    }


    public static void main(String[] args){
        ClientRegistry registry = new ClientRegistry();
        registry.subscribe(new Screen());
        registry.broadcast(new MouseEvent());
    }
}

没有办法验证接收器接口,但它确实是类型安全的,正如你所看到的,我颠倒了顺序,因为现在它是选择接收器而不是其他接收器的事件。