0

My client API encapsulates connections to the server in a class ServerConnection that stores an asyncio.StreamReader/-Writer pair. (For simplicity, I will not use yield from or any other async technique in the code below because it doesn't matter for my question.)

Now, I wonder whether it's better to expose both streams as part of ServerConnection's public interface than to introduce read()/write() methods to ServerConnection which forward calls to the respective stream's methods. Example:

class ServerConnection:
    def __init__(self, reader, writer):
        self.reader = reader
        self.writer = writer

vs.

class ServerConnection:
    def __init__(self, reader, writer):
        self._reader = reader
        self._writer = writer

    def read(self, size):
        return self._reader.read(size)

    def readline(self):
        return self._reader.readline()

    def write(self, data):
        return self._writer.write(data)

    def close(self):
        return self._writer.close()

    # …further proxy methods…

Pros/cons that I'm aware of so far:

Pros: ServerConnection is definitely some kind of bidirectional stream so it'd make sense to have it inherit from a StreamRWPair. Furthermore, it's much more convenient to use server_conn.read() than server_conn.reader.read().

Cons: I would need to define a whole lot of proxy methods. (In my case, I actually use some kind of buffered reader that has additional methods like peek() and so on.) So I thought about creating a base class StreamRWPair similar to Python's io.BufferedRWPair that my ServerConnection can then inherit from. The Python implementation of the io module, however, says the following about BufferedRWPair in the comments:

XXX The usefulness of this (compared to having two separate IO objects) is questionable.

On top of that, my ServerConnection class has several other methods and I'm afraid that, by proxying, I will clutter its attribute namespace and make its usage less obvious.

balu
  • 3,500
  • 4
  • 34
  • 35
  • I believe a sensible answer would depend on how the class is used. Could you edit the question adding some examples where the `ServerConnection` class is used? – brandizzi Jun 30 '14 at 21:11
  • Thank you for your comment, brandizzi. I actually planned to use the above pattern at different places in my code (i.e. with several classes) because I need to deal with all kinds of streams, so I had a hard time trying to find representative examples. Thanks to your question, I realized that this was because my requirements differed depending on the context. Keeping this in mind, I decided to use a `StreamRWPair` class in cases where I need only the stream functionality but stick with the reader/writer separation where the focus of the class / the API actually lies on other functionality. – balu Jul 10 '14 at 21:09

0 Answers0