Как передать один экземпляр абстрактного продукта?
У меня есть абстрактная фабрика девайсов, которая производит телефоны и часы 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 шт):
все зависит от того, чего вы хотите добиться. если вы хотите физически не дать возможность передать 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, но линтер будет ругаться, если передадите не тот тип.
Поменяй в AppleWatch
def connection(self, collaborator: Phone)
на
def connection(self, collaborator:ApplePhone )
Тебе же надо, чтобы AppleWatch при попытке подключить Samsung была ошибка?