Answer the question
In order to leave comments, you need to log in
Why are interfaces not redundant?
OOP textbooks often write that you need to program not at the implementation level, but at the interface level. I don't understand the reason for this, please explain.
For example, I will give the classic Observer pattern. It has abstract Observer and Observable classes with interfaces that inheritors must implement:
#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta):
@abstractmethod
def update(self, message):
pass
class Observable(metaclass=ABCMeta):
@abstractmethod
def register(self, observer):
pass
@abstractmethod
def notify_observers(self, message):
pass
class Newspaper(Observable):
def __init__(self):
self.observers = []
def register(self, observer):
self.observers.append(observer)
def notify_observers(self, message):
for observer in self.observers:
observer.update(message)
def add_news(self, news):
self.notify_observers(news)
class Citizen(Observer):
def __init__(self, name):
self.name = name
def update(self, message):
print('{} получил: {}'.format(self.name, message))
newspaper = Newspaper()
newspaper.register(Citizen('Иван'))
newspaper.register(Citizen('Василий'))
newspaper.add_news('Сообщение')
Answer the question
In order to leave comments, you need to log in
ABC is not required. There is a lot of literature, for example
Mark Summerfield. Python in practice... and others there are examples where the Observer pattern
is created without such inheritance.
Especially everything related to Python 2.7.
But Python's mission is a constant improvement, and it is for this that the concept from Java
abc was introduced into Python 3, which allows you to write more competently, (IMHO, in this case, if the architect sets certain rules, you can be sure that the junior will not be able to forget to write the required implementation.)
This PEP just explains it
https://www.python.org/dev/peps/pep-3119/
In the above code, everything will work without abstract classes. But if you add a line at the end (before ) , then only the execution of the program will end with an error. If the code is more complicated than the one presented, the error may not pop up right away. The same Pycharm will not be able to detect this error in any way.
But if you add type hints to the code:newspaper.add_news('Сообщение')
newspaper.register('abc')
from typing import List
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, message: str) -> None:
pass
class Observable(ABC):
@abstractmethod
def register(self, observer: Observer) -> None:
pass
@abstractmethod
def notify_observers(self, message: str) -> None:
pass
class Newspaper(Observable):
def __init__(self) -> None:
self.observers: List[Observer] = []
def register(self, observer: Observer) -> None:
self.observers.append(observer)
def notify_observers(self, message: str) -> None:
for observer in self.observers:
observer.update(message)
def add_news(self, news: str) -> None:
self.notify_observers(news)
class Citizen(Observer):
def __init__(self, name: str) -> None:
self.name = name
def update(self, message: str) -> None:
print('{} получил: {}'.format(self.name, message))
if __name__ == '__main__':
newspaper = Newspaper()
newspaper.register(Citizen('Иван'))
newspaper.register(Citizen('Василий'))
newspaper.register('abc')
newspaper.add_news('Сообщение')
(VENV~1) D:\My Documents\PycharmProjects\tst>mypy --strict tst105.py
tst105.py:49: error: Argument 1 to "register" of "Newspaper" has incompatible type "str"; expected "Observer"
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question