Я немного озадачен тем, как справиться с этим.
Допустим, у меня есть следующий абстрактный класс клиента веб-сокета и подкласс, который реализует большинство его методов.
Если вместо команды в сообщении провайдеру веб-сокета потребуется изменить пути (как /ws/somesubscription
-> /ws/othersubscription
).Как бы я поступил и реализовал это без определения нового метода в подклассе, который в противном случае был бы почти таким же?
Моя цель, которую я хочу достичь, состоит в том, чтобы мой код оставался сухим, при этом гибко определяя конкретные реализации.
from abc import ABC, abstractmethod
from some_library import some_websocket_client
class WebsocketClientBase(ABC):
def __init__(self):
self.some_implementation_data = None
self.some_other_data = None
self.ws = None
@abstractmethod
def start_socket(self):
self.ws = some_websocket_client()
@abstractmethod
def send_a_message(self, message):
pass
@abstractmethod
def websocket_message(self, message_data):
if not self.ws:
self.start_socket()
url = self.some_implementation_data['url']
message = message_data['msg']
command = message_data['ws_command']
self.ws.send("{'command': {command}, 'message': {message}, 'url': {url}".format(command=command, url=url, message=message))
some_websocket_client.send(message)
class SomeWSClient(WebsocketClientBase):
# This subclass inherits almost everything, except its specific implementation data
def __init__(self):
super().__init__()
self.some_implementation_data = {'url': 'some_url'}
def start_socket(self, message):
super().start_socket(message)
def send_a_message(self, message):
message_data = {
"msg": "my message",
"ws_command": "subscribe"
}
self.websocket_message(message_data)
def websocket_message(self, message_data):
super().websocket_message(message_data)
class ProblemWSClient(WebsocketClientBase):
# Here I encounter problems
def __init__(self):
super().__init__()
self.some_implementation_data = {'url': 'some_url'}
def start_socket(self, message):
super().start_socket(message)
def send_a_message(self, message):
message_data = {
"msg": "my message",
"ws_command": "subscribe"
}
self.websocket_message(message_data)
def websocket_message(self, message_data):
# I need to repeat this, because I can't call the superclass
if not self.ws:
self.start_socket()
# Here I need to apply the new functionality, although largely the same.
command = message_data['ws_command']
url = self.some_implementation_data['url'] + command
message = message_data['msg']
self.ws.send("{'message': {message}, 'url': {url}".format(command=command, url=url, message=message))
some_websocket_client.send(message)