Выбор правильной архитектуры отношений классов

диаграмма классов

Допустим, имеем базовый класс комнаты чата Room. Он в свою очередь подразделяется на 2 подкласса RoomTypeA и RoomTypeB. От этих классов уже наследуются конкретные реализации. Притом, есть класс пользователей комнаты RoomMember, который ссылается на Room по ForeignKey.


Описание проблемы: имея экземпляр (room_member = RoomMember()), обращаясь через связь к комнате и вызывая её метод room_member.room.do_staff() необходимо, чтобы выполнялся метод конкретной реализации комнаты (например, ConcreteRoomTypeA_1).


Сейчас написано решение, что в базовом классе Room в поле concrete_room_class_name сохраняется название класса конкретной комнаты, которая создалась. И когда я хочу через room_member.room вызвать метод do_staff я через __subclassess__ рекурсивно спускаюсь в потомки класса Room, пока не найду класс, название которого совпадает со значением в поле concrete_room_class_name и вызываю метод do_staff. Мне очень не нравится эта реализация. Как сделать эту работу правильно?

Не думаю, что абстрактные классы - мои помощники здесь, ибо тогда не получится иметь только один класс RoomMember.


Ответы (1 шт):

Автор решения: vadim vaduxa
class Room:
    R = {}
    def __init__(self, t): Room.R[t] = self
    @classmethod
    def do_staff(cls, t): cls.R[t].do_staff()

class RoomTypeA(Room): pass
class RoomTypeB(Room): pass

class ConcreteRoomTypeA_1(RoomTypeA):
    def __init__(self, t='A1'):
        RoomTypeA.__init__(self, t)
    def do_staff(self): print('->A1')

class ConcreteRoomTypeB_1(RoomTypeB):
    def __init__(self, t='B1'): RoomTypeB.__init__(self, t)
    def do_staff(self): print('->B1')

class RoomMember:
    def __init__(self, room): self.room = room

if __name__ == '__main__':
    a = ConcreteRoomTypeA_1()
    b = ConcreteRoomTypeB_1()
    room_member = RoomMember(Room)
    room_member.room.do_staff('B1')  # "->B1"
→ Ссылка