Связанные объекты в абстрактной фабрике

Как задавать тип переменных в связанных классах при применении паттерна абстрактная фабрика?

Есть магазин телефонов 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):
        ...

Или стоит поискать другое архитектурное решение в данном случае?


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