簡體   English   中英

需要提取一個接口,但是實現中多了一個方法

[英]Need to extract an interface, but one method is extra in implementation

我編寫了允許將消息從一個對象傳輸到另一個對象的消息傳輸。 所以它有sendreceive等方法

我有兩種實現:

  • InMemoryTransport 在線程間傳輸消息,基於阻塞隊列
  • SocketTransport 通過套接字傳輸消息

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 Parcel receive(String recipient)但是SocketParcelTransport有方法void register(String name, Socket socket) 我不知道該怎么辦。

我可以在InMemoryTransport創建方法register(String compomentName)但是我應該傳遞什么作為第二個參數? 傳遞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 將按以下方式查看,以及如何將Socket傳遞給register()

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 {
...
}
  • 只需創建兩個接口(一個擴展另一個)。 第一個將在內部具有通用方法,第二個將具有額外的方法。
  • 默認接口方法(將偵聽器列表移動到接口)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM