首页 > 解决方案 > 需要提取一个接口,但是在实现中有一种方法是额外的

问题描述

我编写消息传输,允许将消息从一个对象传输到另一个对象。所以它有像send和这样的方法receive

我有两种实现:

InMemoryTransport执行:

public class InMemoryTransport {

    private ConcurrentHashMap<String, BlockingQueue<Parcel>> parcelList = new ConcurrentHashMap<>();

    public void send(Parcel parcel) {
        parcelList.computeIfAbsent(parcel.getReceiverName(), (n) -> new LinkedBlockingQueue<>()).add(parcel);
    }

    public Parcel receive(String recipient) {
        Parcel poll;
        try {
            poll = parcelList.computeIfAbsent(recipient, (n) -> new LinkedBlockingQueue<>()).take();
        } catch (InterruptedException e) {
            return null;
        }
        return poll;
    }
}

SocketTransport执行:

public class SocketParcelTransport {

    private ConcurrentHashMap<String, SocketWraper> listeners = new ConcurrentHashMap<>();

    public void register(String compomentName, Socket socket) throws IOException {
        listeners.putIfAbsent(compomentName, new SocketWraper(socket));
    }

    public void send(Parcel message) {
        try {
            listeners.get(message.getReceiverName()).getOutputStream().writeObject(message);
            listeners.get(message.getReceiverName()).getOutputStream().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Parcel receive(String recipient) {
        try {
            return (Parcel) listeners.get(recipient).getInputStream().readObject();
        } catch (IOException e) {
            // ignore. Just return null in case of io exception
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    class SocketWraper {
        // main idea of this class is to create input and output stream from socket
        public ObjectInputStream getInputStream() throws IOException {
            ...
        }

        public ObjectOutputStream getOutputStream() {
            ...
        }
    }
}

所以,我想为这两个实现提取一个接口。两种实现都有两个相同的方法,可以很容易地提取:void send(Parcel parcel)Parcel receive(String recipient) 但是SocketParcelTransport有方法void register(String name, Socket socket)。我不知道该怎么办。

我可以制作方法register(String compomentName)InMemoryTransport但我应该将什么作为第二个参数传递?传递BlockingQueue<Parcel>将是一个非常糟糕的主意,因为我想封装这些细节。

如果我不会提取void register(String compomentName, Socket socket)到界面,我该如何使用SocketParcelTransport?因为当你使用 DI - 你只使用接口

更新1:

在接口中创建默认方法,所以接口看起来像

public interface ParcelTransport {

    default <T> void register(String componentName, T dataSource) {
     // do nothing   
    };

    void send(Parcel message);

    Parcel receive(String recipient);
}

在这种情况下,我的 SocketParcelTransport 将如下所示,我该如何传递Socketregister()

public class SocketParcelTransport implements ParcelTransport {

    @Override
    public <T> void register(String componentName, T dataSource) {
        Socket socket = dataSource;    // how Can I pass socket here??
    } 

如果我将界面更改为

public interface ParcelTransport<T> {

    default void register(String componentName, T dataSource) {
     // do nothing   
    };
   ...

在那种情况下,我的InMemoryTransport班级会给我警告raw use of parametrized class

public class ThreadsParcelTransport implements ParcelTransport {
...
}

标签: javadesign-patternsinterface

解决方案


  • 只需创建两个接口(一个扩展另一个接口)。第一个将有内部的常用方法,第二个将有额外的方法。
  • 默认接口方法(将侦听器列表移动到接口)

推荐阅读