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. 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.
  2. 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!
  3. 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
  4. 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
  5. 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)
  6. 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)
  7. 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)
  8. 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)
  9. 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)
  10. 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)
  11. 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)
  12. 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)
  13. 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 ...
  14. 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
  15. 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
  16. • 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
  17. • 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?
  18. 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