Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

36
Refactoring. Ruby edition. Anatoli Makarevich @makaroni4

Transcript of Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Page 1: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Refactoring. Ruby edition.Anatoli Makarevich

@makaroni4

Page 2: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Who am I?

Page 3: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Our projects look like

Page 4: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

In next 15 minutes we will

• spice up our knowledge about refactoring

• look at some common smells

• get acquainted with automated code analysis

• become ready to refactor

Page 5: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Refactoring is

but NOT

writing testschanging code

reducing complexity

adding new features

Page 6: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Refactoring != Moving backwards

Page 7: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

To grow fast you need to grow right.

Page 8: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

What refactoring does?

ComplexityReadabilityMaintainabilityExtensibility

Page 9: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

This is scientific!

Martin Fowler, 1999

Page 10: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Your desk books are:

Page 11: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Code Smell

Any symptom in the source code of a program that possibly indicates a deeper

problemKent Beck

Page 12: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Code smells

Long methodDuplicationsHeavy classStupid name

Too many params

Feature envyUbercallback

Complex conditions

Page 13: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Refactoring cycleCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 14: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Find code smellsCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 15: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Check test coverageCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 16: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Write new tests if neededCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 17: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

reFACTORCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 18: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Ensure that tests passCheck testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 19: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Automate tests!Check testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Travis CIJenkins CIGitlab CI

Page 20: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Automate complexity analysis?Check testcoverage

Write testsif needed

Change code

Ensure thattests pass

Check overallcomplexity

Page 21: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Could complexity analysis be automated?

Page 22: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

?How can we process code?

Page 23: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

S-expressions

Page 24: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Sexp operator

Page 25: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Sexp body

Page 26: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Automated analysis

• Long methods

• Complex class

• Stupid variable name

Page 27: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Long method

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Find method Sexp :defn

Page 28: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Long method

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Find method Sexp :defn

Count sexp operators

Page 29: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Complex class

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Find method Sexp :class

Page 30: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Complex class

s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Find method Sexp :class

Cound weights of Sexp operators

Page 31: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Stupid variable name

s(:class, :HomerSimpson, s(:const, :BlahBlahBlah), s(:defn, :donuts, s(:args), s(:call, nil, :fist)), s(:defn, :beersnstuff, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))

Page 32: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Automated analysis

Page 33: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Refactoring!=

Rehacktoring

@katrinyx

Page 34: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

It is about perception

We READ code, NOT COMPILE it.

Page 35: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

After this talk do:

• gem install flog

• gem install flay

• gem install reek

• flog PROJECT_PATH

• flay PROJECT_PATH

• reek PROJECT_PATH

Page 36: Рефакторинг Ruby-кода / Анатолий Макаревич (Evrone)

Let’s refactor!

Anatoli Makarevich@makaroni4