Связанные объекты в абстрактной фабрике
Как задавать тип переменных в связанных классах при применении паттерна абстрактная фабрика?
Есть магазин телефонов Android и IOS, в магазине можно купить сам телефон и запросить сервисного инженера для его ремонта. Однако каждый инженер может чинить соответствующий тип телефона.
Должны ли методы repair_phone(self, phone: Phone) инженеров ожидать объект реализующий интерфейс Phone, если они нуждаются только в методах специфичных для своего телефона, или имеющих разные типы аргументов.
Вопрос схож с этим.
class Phone(ABC):
@abstractmethod
def turn_on_silent_mode(self):
pass
@abstactmethod
def make_call(self, number):
pass
class IPhone(Phone):
# Abstract methods realization...
# IPhone requires special password to unlock os
def unlock_os(self, special_password):
...
def iphone_specific_operation(self, parameter: str):
...
return 'Iphone specific operation done'
class AndroidPhone(Phone):
# Abstract methods realization...
# Android phone doesn't need password
def unlock_os(self):
...
def android_specific_operation(self, other_parameter: int):
...
return 'Android specific operation done'
class ServiceEngineer(ABC):
@abstractmethod
def get_repair_tax_value(self) -> int:
pass
@abstractmethod
def repair_phone(self, phone: Phone):
pass
class IPhoneServiceEngineer(ServiceEngineer):
# Abstract methods realization...
def repair_phone(self, phone: Phone):
# IPhone engineer knows special password
phone.unlock_os(special_password)
phone.iphone_specific_operation(parameter)
...
class AndroidServiceEngineer(ServiceEngineer):
# Abstract methods realization...
def repair_phone(self, phone: Phone):
# Android phone doesn't need password
phone.unlock_os()
phone.android_specific_operation(other_parameter)
...
class PhoneStore(ABC):
@abstractmethod
def buy_phone(self) -> Phone:
@abstractmethod
def create_service_engineer(self) -> ServiceEngineer:
class IPhoneStore(PhoneStore):
def buy_phone(self) -> Phone:
return IPhone()
def create_service_engineer(self) -> ServiceEngineer:
return IPhoneServiceEngineer()
class AndroidStore(PhoneStore):
def buy_phone(self) -> Phone:
return AndroidPhone()
def create_service_engineer(self) -> ServiceEngineer:
return AndroidServiceEngineer()
def main():
phone_store = IPhoneStore()
phone = phone_store.buy_phone()
phone.make_call()
service_engineer = phone_store.create_service_engineer()
tax = service_engineer.get_repair_tax_value()
service_engineer.repair_phone(phone)
phone_store = AndroidStore()
phone = phone_store.buy_phone()
phone.make_call()
service_engineer = phone_store.create_service_engineer()
tax = service_engineer.get_repair_tax_value()
service_engineer.repair_phone(phone)
Правильно ли выделить два дополнительных интерфейса (расширяющих интерфейс Phone), и указать их в методах repair инженеров?
class Phone(ABC):
@abstractmethod
def turn_on_silent_mode(self):
pass
@abstactmethod
def make_call(self, number):
pass
class IPhone(Phone):
@abstractmethod
def unlock_os(self, special_password):
...
@abstractmethod
def iphone_specific_operation(self, parameter):
...
# Concrete IPhone
class IPhoneXR(Phone):
# Abstract methods realization...
class AndroidPhone(Phone):
@abstractmethod
def unlock_os(self):
...
@abstractmethod
def android_specific_operation(self, other_parameter):
...
# Concrete Android phone
class Samsung(AndroidPhone):
# Abstract methods realization...
class IPhoneServiceEngineer(ServiceEngineer):
# Abstract methods realization...
def repair_phone(self, phone: IPhone):
...
class AndroidServiceEngineer(ServiceEngineer):
# Abstract methods realization...
def repair_phone(self, phone: AndroidPhone):
...
Или стоит поискать другое архитектурное решение в данном случае?