Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vamos falar de refatoração

Vamos falar de refatoração

Slides da palestra apresentada na Python Floripa

Elias Dorneles

December 15, 2016
Tweet

More Decks by Elias Dorneles

Other Decks in Programming

Transcript

  1. Vamos falar de
    refatoração
    Elias Dorneles
    @eliasdorneles

    View Slide

  2. O que é refatorar, afinal?

    View Slide

  3. Refatorar é...
    ● Mudar a estrutura do código
    ● SEM mudar o comportamento externo
    ● Visando melhorar o design
    Em geral, envolve fazer uma série de
    pequenas mudanças preservando
    o funcionamento.

    View Slide

  4. Objetivo é acomodar melhor
    as próximas mudanças

    View Slide

  5. Refatorar NÃO é...
    ● Reescrever um módulo/função
    ● Alterar um código, mudando
    o comportamento
    ● Adicionar ou remover um recurso
    Mesmo que essas coisas visem melhorar o design!

    View Slide

  6. Hm, por que é tão
    importante distinguir?

    View Slide

  7. Primeiro, refatorar requer um lock
    Reestruturar código preservando comportamento é algo
    que precisa ser feito de maneira “atômica”
    Ou seja, quando estiver refatorando, não faça outras
    coisas ao mesmo tempo: apenas refatore

    View Slide

  8. Metáfora dos chapéus
    Source: http://martinfowler.com/articles/workflowsOfRefactoring/#2hats

    View Slide

  9. Segundo, o escopo e os riscos são diferentes

    View Slide

  10. Refatorar é pra ser um hábito
    ● Cotidiano, como tomar água, abrir o editor, rodar o
    código, rodar os testes
    ● Não é algo que você precise pedir permissão pro
    gerente
    A seguir vamos ver alguns exemplos

    View Slide

  11. Exemplos: renomear variável
    current_page = int(find_element_by_css('.page.active'))
    if current_page < total_pages:
    goto_page(current_page + 1)
    c = int(find_element_by_css('.page.active'))
    if c < total_pages:
    goto_page(c + 1)

    View Slide

  12. Exemplos: extrair variável
    if cur_page < max(int(x) for x in page_links):
    goto_page(cur_page + 1)
    total_pages = max(int(x) for x in page_links)
    if cur_page < total_pages:
    goto_page(cur_page + 1)

    View Slide

  13. Exemplos: inline da variável (inverso de extrair)
    if cur_page < max(int(x) for x in page_links):
    goto_page(cur_page + 1)
    total_pages = max(int(x) for x in page_links)
    if cur_page < total_pages:
    goto_page(cur_page + 1)

    View Slide

  14. Exemplos: extrair função
    if cur_page < max(int(x) for x in page_links):
    goto_page(cur_page + 1)
    def get_total_pages():
    return max(int(x) for x in page_links)
    if cur_page < get_total_pages():
    goto_page(cur_page + 1)

    View Slide

  15. Exemplos: extrair função (opção 2)
    if cur_page < max(int(x) for x in page_links):
    goto_page(cur_page + 1)
    def get_total_pages(all_pages):
    return max(int(x) for x in all_pages)
    if cur_page < get_total_pages(page_links):
    goto_page(cur_page + 1)

    View Slide

  16. Extrair função/método
    é a minha
    refatoração favorita! =)

    View Slide

  17. Exemplos: inline da função (inverso de extrair)
    if cur_page < max(int(x) for x in page_links):
    goto_page(cur_page + 1)
    def get_total_pages(all_pages):
    return max(int(x) for x in all_pages)
    if cur_page < get_total_pages(page_links):
    goto_page(cur_page + 1)

    View Slide

  18. É bem provável que
    você já faça essas
    coisas, mesmo que não
    use esses nomes

    View Slide

  19. Que outras
    refatorações existem?

    View Slide

  20. http://refactoring.com/catalog

    View Slide

  21. E Python?
    Existem refatorações
    pythônicas, né?

    View Slide

  22. YESSS! Alguns exemplos:
    ● Substituir retorno múltiplo por namedtuple
    ● Extrair context manager
    ● Vários exemplos nessas talks do Raymond Hettinger:
    ○ Beyond PEP-8:
    http://pyvideo.org/pycon-us-2015/beyond-pep-8-best-practices-for-be
    autiful-inte.html
    ○ Transforming Code into Beautiful, Idiomatic Python:
    http://pyvideo.org/pycon-us-2013/transforming-code-into-beautiful-id
    iomatic-pytho.html (Slides)

    View Slide

  23. Substituir retorno múltiplo por namedtuple
    from collections import namedtuple
    Interval = namedtuple('Interval', 'start end')
    def fetch_last_interval(conn):
    query = "SELECT start_time,end_time FROM facts ORDER by end_time LIMIT 1"
    start, end = next(conn.execute(query))
    return Interval(start, end) # Interval(start=u'2016-12-15 13:52:45', end=None)
    def fetch_last_interval(conn):
    query = "SELECT start_time,end_time FROM facts ORDER by end_time LIMIT 1"
    start, end = next(conn.execute(query))
    return start, end # (u'2016-12-15 13:52:45', None)

    View Slide

  24. Extrair context manager
    import tempfile
    _, arq = tempfile.mkstemp()
    try:
    # processa o
    # arquivo aqui
    # ...
    finally:
    os.remove(arq)
    import tempfile
    from contextlib import contextmanager
    @contextmanager
    def arquivo_temp():
    _, arq = tempfile.mkstemp()
    try:
    yield arq
    finally:
    os.remove(arq)
    with arquivo_temp() as arq:
    # processa arquivo aqui ...

    View Slide

  25. Refatoração & YAGNI
    ● Humanos são péssimos em antecipar mudanças
    ● “You Aren’t Gonna Need It”: princípio que preza pela
    simplicidade, não olhando muito para o futuro,
    evitando complexidade desnecessária
    ● Você precisa refatorar para obter simplicidade
    ● Refatore para os casos de uso conhecidos

    View Slide

  26. Ok, refatorar é legal!
    Como posso fazer mais e melhor?

    View Slide

  27. Refatorar precisa ser fácil!
    Para isso, é preciso:
    ● Dominar profundamente a linguagem
    ○ Quanto mais coisas você souber fazer de cabeça, mais fácil fica
    ● Escrever testes
    ○ É uma necessidade básica
    ● Obter boas ferramentas
    ● Educar-se e praticar
    ○ Ler livros, ler código dos outros, tentar refactor grande num branch

    View Slide

  28. ● Qual a ferramenta de refatoração mais popular entre
    os Pythonistas?
    Sobre ferramentas

    View Slide

  29. ● Qual a ferramenta de refatoração mais popular entre
    os Pythonistas?
    ○ grep (e similares)
    ○ Será que não podemos fazer melhor?
    “The cobbler’s children have no shoes”
    Sobre ferramentas

    View Slide

  30. ● https://github.com/python-rope/rope
    ● Biblioteca de refatorações
    ○ e outras coisas mais (jump to definition)
    ● Plugins para VIM/Emacs/Sublime:
    ○ UI espartana
    ○ Poucas pessoas conhecem & usam
    ● Pessoalmente, uso pouco, a UI me assusta
    ○ Tenho mappings no VIM para as refatorações mais simples
    Rope -- is there hope?

    View Slide

  31. DEMO no VIM

    View Slide

  32. Alguém aí já
    gritou
    Pycharm?

    View Slide

  33. Thanks!
    Elias Dorneles
    @eliasdorneles
    Algumas referências
    ● http://refactoring.com
    ● http://martinfowler.com/articles/
    workflowsOfRefactoring
    ● https://www.infoq.com/br/articles
    /is-design-dead
    ● https://pythonhelp.wordpress.co
    m/2016/10/01/usando-comando-
    with-para-evitar-acoplamento-te
    mporal/
    ● Livro do Martin Fowler
    ● Livro The Pragmatic Programmer

    View Slide