I'm in the process of writing an bidirectional, asynchronous socket server and server handler. The base handler class I'm working off of is as follows:
class BaseAsyncSocketHandler:
async def send(self, data: bytes) -> int
However, I want to write a subclass that sends two arguments, an event and arbitrary corresponding data, which suggests the signature:
async def send(self, event: str, data: object) -> int:
return await super().send(event_data_magic_to_bytes(event, data))
Unfortunately, this violates the Liskov substitution principle, and I don't think writing it as a mixin will makes the situation any better, so I'm hoping somebody has either seen this before or can think of a better design pattern (or tell me this is an unnecessary abstraction in the first place).
Best Answer
In the end, I settled on providing the following:
This way the user can implement subsets of the send method while using the base send method provided by the socket wrapper. As to why I wanted to use
send
instead of just creating another class method likesend_event
, I think I mostly just wanted the interface to the class to remain compact and usable while allowing for different socket methodologies.