Z
Z
zlodiak2019-03-09 00:01:18
Python
zlodiak, 2019-03-09 00:01:18

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('Сообщение')

However, the code will become noticeably simpler if you stop using abstract classes (and hence interfaces). Please tell me possible scenarios for the development of the presented code, in which there will be inconvenience from the absence of Observer and Observable metaclasses

Answer the question

In order to leave comments, you need to log in

2 answer(s)
L
LODIII, 2019-03-09
@zlodiak

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/

A
Andy_U, 2019-03-09
@Andy_U

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('Сообщение')

then when using Pycharm or mypy, they will immediately swear at a type error:
(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"

That is, if you write small programs exclusively for yourself in notepad, you can do it without abstract classes and type hints. But in all other cases - it is better to act professionally.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question