Как передать один экземпляр абстрактного продукта?

У меня есть абстрактная фабрика девайсов, которая производит телефоны и часы Apple и Samsung. Часы Apple корректно работают только с одним результатом(телефоном Apple), но принимают любой экземпляр телефонов в качестве аргумента. Как я могу передать только экземпляр телефона Apple и могу ли я это сделать через функцию isinstance ?

from abc import ABC, abstractmethod


class DeviceFactory(ABC):

    @abstractmethod
    def create_phone(self) -> Phone:
        pass

    @abstractmethod
    def create_watch(self) -> Watch:
        pass


class AppleFactory(DeviceFactory):

    def create_phone(self) -> Phone:
        return ApplePhone()

    def create_watch(self) -> Watch:
        return AppleWatch()


class SamsungFactory(DeviceFactory):

    def create_phone(self) -> Phone:
        return SamsungPhone()

    def create_watch(self) -> Watch:
        return SamsungWatch()


class Phone(ABC):

    @abstractmethod
    def GetNamePhone(self) -> str:
        pass


class ApplePhone(Phone):
    def GetNamePhone(self) -> str:
        return "Телефон Apple."


class SamsungPhone(Phone):
    def GetNamePhone(self) -> str:
        return "Телефон Samsung."


class Watch(ABC):

    @abstractmethod
    def GetNameWatch(self) -> None:
        pass

    @abstractmethod
    def connection(self, collaborator: Phone) -> None:
        pass


class AppleWatch(Watch):
    def GetNameWatch(self) -> str:
        return "Часы Apple."

    def connection(self, collaborator: Phone) -> str:
        result = collaborator.GetNamePhone()
        return f"Часы Apple можно подключить к {result}"


class SamsungWatch(Watch):
    def GetNameWatch(self) -> str:
        return "Часы Samsung."

    def connection(self, collaborator: Phone):
        result = collaborator.GetNamePhone()
        return f"Часы Samsung можно подключить к {result}"


def client_code(factory: DeviceFactory) -> None:
    product_a = factory.create_phone()
    product_b = factory.create_watch()

    print(f"{product_b.connection(product_a)}", end="")


if __name__ == "__main__":
    client_code(AppleFactory())
    print("\n")
    client_code(SamsungFactory())

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

Автор решения: finally

все зависит от того, чего вы хотите добиться. если вы хотите физически не дать возможность передать ApplePhone в SamsungWatch.connection, то можно сделать так:

class SamsungWatch(Watch):
    def GetNameWatch(self) -> str:
        return "Часы Samsung."

    def connection(self, collaborator: Phone):
        if not isinstance(collaorator, SamsungPhone):
            raise SomeError
        result = collaborator.GetNamePhone()
        return f"Часы Samsung можно подключить к {result}"

в таком случае вы не сможете запустить код.

если же вы хотите сделать это неявным правилом, то можно, т.к это уже не абстракция, а конкретная реализация в type hint к принимаемому collaborator указать явно SamsungPhone вместо Phone. вы сохраните уровень абстракции, т.к SamsungPhone это надстройка над Phone, но линтер будет ругаться, если передадите не тот тип.

→ Ссылка
Автор решения: xmikex

Поменяй в AppleWatch

def connection(self, collaborator: Phone)

на

def connection(self, collaborator:ApplePhone )

Тебе же надо, чтобы AppleWatch при попытке подключить Samsung была ошибка?

→ Ссылка