Princípio de inversão de dependência do Python

Resumo : neste tutorial, você aprenderá sobre o princípio de inversão de dependência do Python para tornar seu código hi

Introdução ao princípio de inversão de dependência

O princípio de inversão de dependência é um dos cinco princípios SOLID na programação orientada a objetos:

O princípio da inversão de dependência afirma que:

  • Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.
  • As abstrações não devem depender de detalhes. Os detalhes devem depender de abstrações.

O princípio de inversão de dependência visa reduzir o acoplamento entre classes criando uma camada de abstração entre elas.

Veja o exemplo a seguir:

class FXConverter:
    def convert(self, from_currency, to_currency, amount):
        print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
        return amount * 1.2


class App:
    def start(self):
        converter = FXConverter()
        converter.convert('EUR', 'USD', 100)


if __name__ == '__main__':
    app = App()
    app.start()Linguagem de código:  Python  ( python )

Neste exemplo, temos duas classes FXConvertere App.

A FXConverterclasse usa uma API de um terceiro FX imaginário para converter um valor de uma moeda para outra. Para simplificar, codificamos a taxa de câmbio como 1.2. Na prática, você precisará fazer uma chamada de API para obter a taxa de câmbio.

A Appclasse possui um start()método que usa uma instância da FXconverterclasse para converter 100 EUR em USD.

O Appé um módulo de alto nível. No entanto, The Appdepende muito da FXConverterclasse que depende da API do FX.

No futuro, se a API do FX mudar, o código será quebrado. Além disso, se quiser usar uma API diferente, você precisará alterar a Appclasse.

Para evitar isso, você precisa inverter a dependência para que a FXConverterclasse precise se adaptar à Appclasse.

Para fazer isso, você define uma interface e torna-a Appdependente dela em vez de FXConverteruma classe. E então você altera FXConverterpara ficar de acordo com a interface.

Primeiro, defina uma classe abstrata CurrencyConverter que atue como uma interface. A CurrencyConverterclasse possui o convert()método que todas as suas subclasses devem implementar:

from abc import ABC


class CurrencyConverter(ABC):
    def convert(self, from_currency, to_currency, amount) -> float:
        pass
Linguagem de código:  Python  ( python )

Segundo, redefina a FXConverterclasse para que ela herde da CurrencyConverterclasse e implemente o convert()método:

class FXConverter(CurrencyConverter):
    def convert(self, from_currency, to_currency, amount) -> float:
        print('Converting currency using FX API')
        print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
        return amount * 2Linguagem de código:  Python  ( python )

Terceiro, adicione o __init__método à Appclasse e inicialize o CurrencyConverterobjeto ‘:

class App:
    def __init__(self, converter: CurrencyConverter):
        self.converter = converter

    def start(self):
        self.converter.convert('EUR', 'USD', 100)Linguagem de código:  Python  ( python )

Agora, a Appclasse depende da CurrencyConverterinterface, não da FXConverterclasse.

O seguinte cria uma instância do FXConvertere passa-a para o App:

if __name__ == '__main__':
    converter = FXConverter()
    app = App(converter)
    app.start()Linguagem de código:  JavaScript  ( javascript )

Saída:

Converting currency using FX API
100 EUR = 120.0 USD

No futuro, você poderá oferecer suporte a outra API de conversor de moeda criando uma subclasse da CurrencyConverterclasse. Por exemplo, o seguinte define a AlphaConverterclasse que herda do CurrencyConverter.

class AlphaConverter(CurrencyConverter):
    def convert(self, from_currency, to_currency, amount) -> float:
        print('Converting currency using Alpha API')
        print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
        return amount * 1.15Linguagem de código:  Python  ( python )

Como a AlphaConvertclasse herda da CurrencyConverterclasse, você pode usar seu objeto na Appclasse sem alterar a Appclasse:

if __name__ == '__main__':
    converter = AlphaConverter()
    app = App(converter)
    app.start()Linguagem de código:  JavaScript  ( javascript )

Saída:

Converting currency using Alpha API
100 EUR = 120.0 USD

Junte tudo.

from abc import ABC


class CurrencyConverter(ABC):
    def convert(self, from_currency, to_currency, amount) -> float:
        pass


class FXConverter(CurrencyConverter):
    def convert(self, from_currency, to_currency, amount) -> float:
        print('Converting currency using FX API')
        print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
        return amount * 1.15


class AlphaConverter(CurrencyConverter):
    def convert(self, from_currency, to_currency, amount) -> float:
        print('Converting currency using Alpha API')
        print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
        return amount * 1.2


class App:
    def __init__(self, converter: CurrencyConverter):
        self.converter = converter

    def start(self):
        self.converter.convert('EUR', 'USD', 100)


if __name__ == '__main__':
    converter = AlphaConverter()
    app = App(converter)
    app.start()
Linguagem de código:  Python  ( python )

Resumo

  • Use o princípio de inversão de dependência para tornar seu código mais robusto, tornando o módulo de alto nível dependente da abstração, não da implementação concreta.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *