1
resposta

[Projeto] Como deixar o código mais legível?

Consegui realizar a atividade mas achei meu código cansativo de se ler. Alguma sugestão de como posso melhora-lo?

from validate_docbr import CPF, CNPJ


class ValidarDocumentoEmUmaUnicaClasse:
    def __init__(self, documento, tipo_documento):
        self._documento = documento
        self._tipo_documento = tipo_documento.lower()
        self.validar_documento(documento, tipo_documento)

    def __str__(self):
        return self.formartar_documento()

    def validar_documento(self, documento, tipo_documento):
        if tipo_documento == "cpf":
            if CPF().validate(documento):
                return self.documento
            else:
                raise ValueError("Documento inválido")

        elif tipo_documento == "cnpj":
            if CNPJ().validate(documento):
                return self.documento
            else:
                raise ValueError("CNPJ inválido")
        else:
            raise ValueError("Documento Inválido")

    @property
    def documento(self):
        return self._documento

    @property
    def tipo_documento(self):
        return self._tipo_documento

    @documento.setter
    def documento(self, novo_documento):
        self._documento = novo_documento

    @tipo_documento.setter
    def tipo_documento(self, novo_documento):
        self._tipo_documento = novo_documento

    def formartar_documento(self):
        if self.tipo_documento == "cpf":
            validador_cpf = CPF()
            return validador_cpf.mask(self.documento)
        elif self.tipo_documento == "cnpj":
            validador_cnpj = CNPJ()
            return validador_cnpj.mask(self.documento)
1 resposta

Oi @Yan, algumas sugestões:

1) Uso desnecessário de Setters e Getters:

Seus setters e getters não fazem nada, apenas atribuem diretamente os parâmetros ou retornam diretamente os atributos.

Considere substituí-los por variáveis públicas. Somente utilize setters e getters se isso for realmente necessário

2) Excesso de indentação:

Quanto mais indentação em um código, mais difícil de ler.

Tenha em mente o limite máximo de 3 níveis de indentação, que deve ser suficiente para qualquer código. Acima disso você já deve começar a pensar em outras estratégias para refatorar seu código, como dividir sua função em funções menores, por exemplo.

Este artigo do Nick Consentino fala mais sobre a questão do "Excessive Nesting" . Este vídeo mostra dicas de como evitar indentação excessiva.

3. Troque seus if por dict:

No seu código, "if self.tipo_documento == "cpf":" apareceu diversas vezes.

Veja o atributo validator na classe abaixo. Em vez de utilizar um if, ela faz a busca de uma chave em um dicionário para encontrar o validador correto.

Imagine que surja a demanda do seu código atender a outros tipos de documento, como "CNH" ou "Passaporte". No seu código seria necessário adicionar um monte de novos ifs.

O Clean Code recomenda que seus métodos sejam extensíveis e fechados para mudanças. No código abaixo, bastaria adicionar o novo tipo no dicionário validators.

Código Refatorado:

from validate_docbr import CPF, CNPJ

class Document:
    validators = {"cpf": CPF, "cnpj": CNPJ}

    def __init__(self, document, document_type: str):
        self.document_type(document_type)
        self.document = document
        self.validator = self.validators.get(self.__document_type)
        self.validate()

    def __str__(self):
        return self.validator().mask(self.document)

    def validate(self):
        if self.validator().validate(self.document):
            return self.document
        raise ValueError("Documento inválido")

    @property
    def document_type(self):
        return self.__document_type

    @document_type.setter
    def document_type(self, new_document_type: str):
        if new_document_type.lower() not in self.validators:
            raise ValueError("Tipo de documento inválido")
        self.__document_type = new_document_type.lower()
        self.validator = self.validators.get(self.__document_type)