Education 1.1 Help

Принцип разделения интерфейсов

Принцип разделения интерфейсов гласит что: «Ни один клиент не должен зависеть от методов, которые он не использует». Принцип разделения интерфейсов был предложен Робертом К. Мартином, когда он консультировал компанию Xerox. Принцип разделения интерфейсов предполагает создание небольших интерфейсов, известных как «ролевые интерфейсы», вместо большого интерфейса, состоящего из нескольких методов. Разделяя методы по ролям на более мелкие интерфейсы, клиенты будут зависеть только от методов, которые имеют к ним отношение. Допустим, мы разрабатываем приложение для различных коммуникационных устройств. Мы говорим, что устройство связи – это устройство, которое будет иметь одну или несколько из следующих функций: совершать звонки, отправлять SMS или искать в Интернете. Итак, мы создаем интерфейс с именем CommunicationDevice и добавляем соответствующие абстрактные методы для каждой из этих функций, чтобы любой создаваемый класс смог реализовать эти методы. Затем мы создаем класс SmartPhone с помощью интерфейса CommunicationDevice и реализуем функционал абстрактных методов. До сих пор все было в порядке. Теперь предположим, что нам нужно создать стационарный телефон. Он тоже является устройством связи, поэтому мы создаем новый класс LandlinePhone через тот же интерфейс CommunicationDevice. Именно здесь мы сталкиваемся с проблемой из-за объемного интерфейса CommunicationDevice. В классе LandlinePhone мы реализовываем метод make_calls(), но поскольку мы также наследуем абстрактные методы send_sms() и browse_internet(), мы должны предоставить реализацию и этих двух абстрактных методов в классе LandlinePhone, даже если они в принципе неприменимы к этому виду телефонов. Мы можем либо создать исключение, либо оставить pass вместо реализации, но нам все равно нужно ее предоставить.

from abc import ABCMeta, abstractmethod class CommunicationDevice(): @abstractmethod def make_calls(): pass @abstractmethod def send_sms(): pass @abstractmethod def browse_internet(): pass class SmartPhone(CommunicationDevice): def make_calls(): #implementation pass def send_sms(): #implementation pass def browse_internet(): #implementation pass class LandlinePhone(CommunicationDevice): def make_calls(): #implementation pass def send_sms(): #just pass or raise exception as this feature is not supported pass def browse_internet(): #just pass or raise exception as this feature is not supported pass
interface CommunicationDevice { public function make_calls(); public function send_sms(); public function browse_internet(); } class SmartPhone implements CommunicationDevice { public function make_calls() { // TO DO } public function send_sms() { // TO DO } public function browse_internet() { // TO DO } } class LandlinePhone implements CommunicationDevice { public function make_calls() { // TO DO } public function send_sms() { // just pass or raise exception as this feature is not supported } public function browse_internet() { // just pass or raise exception as this feature is not supported } }

Все можно исправить, следуя принципу разделения интерфейсов, как в примере ниже. Вместо создания большого интерфейса мы создаем более маленькие ролевые интерфейсы для каждого метода. Соответствующие классы будут использовать только связанные интерфейсы.

from abc import ABCMeta, abstractmethod class CallingDevice(): @abstractmethod def make_calls(): pass class MessagingDevice(): @abstractmethod def send_sms(): pass class InternetbrowsingDevice(): @abstractmethod def browse_internet(): pass class SmartPhone(CallingDevice, MessagingDevice, InternetbrowsingDevice): def make_calls(): #implementation pass def send_sms(): #implementation pass def browse_internet(): #implementation pass class LandlinePhone(CallingDevice): def make_calls(): #implementation pass
interface CallingDevice { public function make_calls(); } interface MessagingDevice { public function send_sms(); } interface InternetbrowsingDevice { public function browse_internet(); } class SmartPhone implements CallingDevice, MessagingDevice, InternetbrowsingDevice { public function make_calls() { // TO DO } public function send_sms() { // TO DO } public function browse_internet() { // TO DO } } class LandlinePhone implementsCallingDevice { public function make_calls() { // TO DO } }
Last modified: 12 June 2024