12.2 Mix-Ins
Se usarmos herança múltipla, geralmente é uma boa ideia projetarmos nossas classes de uma maneira que evite o tipo de ambiguidade descrita acima - apesar do Python possuir o MRO, em sistemas grandes a herança múltipla ainda pode causar muitos problemas.
Uma maneira de fazer isso é dividir a funcionalidade opcional em mix-ins. Um mix-in é uma classe que não se destina a ser independente - existe para adicionar funcionalidade extra a outra classe através de herança múltipla. A ideia é que classes herdem estes mix-ins, essas “misturas de funcionalidades”.
Por exemplo, nossa classe Autenticavel pode ser um mix-in, já que ela existe apenas para acrescentar a funcionalidade de ser autenticável, ou seja, para herdar seu método autentica .
Nossa classe Autenticavel já se comporta como um Mix-In . No Python não existe uma maneira específica de criar mix-ins. Os programadores, por convenção e para deixar explícito a classe como um mix-in, colocam o termo ‘MixIn’ no nome da classe e utilizam através de herança múltipla:
class AutenticavelMixIn:def autentica(self, senha): # verifica senhaCada mix-in é responsável por fornecer uma peça específica de funcionalidade opcional. Podemos ter outros mix-ins no nosso sistema:
class AtendimentoMixIn:def cadastra_atendimento(self): # faz cadastro atendimento
def atende_cliente(self): # faz atendimento
class HoraExtraMixIn:def calcula_hora_extra(self, horas): # calcula horas extras
12.2 MIX-INS
E podemos misturá-los nas classes de nosso sistema:
class Gerente(Funcionario, AutenticavelMixIn, HoraExtraMixIn): passclass Diretor(Funcionario, AutenticavelMixIn): passclass Cliente(AutentivavelMixIn): passclass Escriturario(Funcionario, AtentimentoMixIn): passRepare que nossos mix-ins não têm um método init () . Muitos mix-ins apenas fornecem métodos adicionais, mas não inicializam nada. Isso às vezes significa que eles dependem de outras propriedades que já existem em suas filhas. Cada mix-in é responsável por fornecer uma peça específica de funcionalidade opcional - é um jeito de compor classes.
Poderíamos estender este exemplo com mais misturas que representam a capacidade de pagar taxas, a capacidade de ser pago por serviços, e assim por diante - poderíamos então criar uma hierarquia de classes relativamente plana para diferentes tipos de classes de funcionário que herdam Funcionario e alguns mix-ins .
Essa é uma das abordagens de se usar herança múltipla, mas ela é bastante desencorajada. Caso você utilize, opte por mix-ins sabendo de suas desvantagens. Usando em sistemas grandes, podem ocorrer colisões com nomes de métodos, métodos substituídos acidentalmente, hierarquia de classes pouco clara e dificuldade de ler e entender classes compostas por muitos mix-ins, dentre outras desvantagens. O problema da herança múltipla permanece.
Outra abordagem possível é definir funções fora de classes, digamos em um módulo e fazer chamadas dessas funções passando nossos objetos. Mas isso é um afastamento radical do paradigma orientado a objetos, que é baseada em métodos definidos dentro das classes.