samedi 14 décembre 2019

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

I write message transport that allows to transfer messages from one object to another. So it has methods like send and receive

And I have two kind of implementations:

  • InMemoryTransport transfers message between threads and based on blocking qeueue
  • SocketTransport transferts messages throught socket

InMemoryTransport implementation:

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 implementation:

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() {
            ...
        }
    }
}

So, I want to extract an interface for these two implementations. Both implementations have two same methods that can be easily extracted: void send(Parcel parcel) and Parcel receive(String recipient) But SocketParcelTransport have method void register(String name, Socket socket). I don't know what to do with it.

I can make method register(String compomentName) in InMemoryTransport but what should I pass as the second parameter? Passing BlockingQueue<Parcel> will be really bad idea because I want to encapsulate such details.

If I will not extract void register(String compomentName, Socket socket) to interface, how can I use SocketParcelTransport? Becase when you use DI - you only work with interfaces

Aucun commentaire:

Enregistrer un commentaire