CODE REFACTOR STRATEGY
byTracy LOISEL, Lead Developer at monAlbumPhoto.fr
Geneva, september the 28th
THANKS
• Many thanks to Geneva Ruby Brigade, the
geneva ruby on rails developers group
• Many thanks to monAlbumPhoto.fr to let me
share with you our experience
WHY CODE REFACTOR ?
• to code faster next time
and not by monkey
patching
• to debug easier next time
without hurting yourself
• to build sustainable code
with services oriented
architecture
AND WHY
A STRATEGY FORTHAT ?
• to be far beyond esthetic
matters and keep developers
in peace
• to share a same behave while
refactoring with team-mates
• to let all your developers take
part of the project, no matter
if they feel confident enough
to refactor code from other
developers
THE CONTEXT AT MAP
• monAlbumPhoto is one the main photos printing services in France
• the company started at 2004 and has been acquired by M6 Group in 2010
• it is one the main Ruby on Rails project in Europe said Jean-DanielVouille, CTO at
famous Echos newsgroup
• 20 developpers work in Paris for the IT department under the management of our
CTO Benjamin Grelié, while we outsource also in Russia and India
• the service is powered by a google cloud architecture with above 20 production
servers
• we have a factory of 5000 squared meters in Picardie (France)
THREE MORE WAYS
TO DON’T REPEAT
EACH OTHER
MODEL CONCERNS
• concerns let you share code between models
• think about an email validation regexp. In a single
app many model would include an email_address
attributes
• standardize its validation inside a concern
CONTROLLER CONCERNS
• concerns let you share code between controllers
too
• like constants or methods called within
before_filter
POLYMORPHIC MODEL
POLYMORPHIC MODEL
• think about price information, in a single app you
could have many objects with price attributes
because they are billable
• now think about the mess if each developer design
his own price for his current model ? how many
files 2 or 3 years after ?
POLYMORPHIC MODEL
• polymorphic model and concern are a solution to
manage a kind of information that is use
elsewhere with not necessary variations (cost vs
value, amount vs total, etc)
• standardize implementation of an information with
a polymorphic model
SERVICE-ORIENTED
ARCHITECTURE
THE BEGINNING
• For long term, with developers coming then leaving, we
want to make monkey patch an irregular way to code
• We want to slim down our controllers and models.
Concerns failed to do it in long terms, it’s not enough
• We want to know instantly where a function is located.
No more magic calls and methods that make too
much, even the coffee.
OUR SPLITS
• /app/models is for relations, validations, search strategy and other strategy
definition
• /app/controllers is to accept HTTP requests and respond with data
• /app/models/concerns is to share code between models
• /app/models/concerns is to share code between controllers
• /app/services is for Service Object that accept input, perform works and
return result
• /app/supports is to extend ActiveRecord::Base with a service object
NAMING CONVENTIONS
• Each concern name is appended with ableConcern term like in
AmountableConcern
• Each module support name is appended with Support term like in
CloningSupport
• Each service object name is appended with Service term like in
UserAddressesService and is prefixed with Active term when it play
for a single model like in ActiveFeedService
• We avoid verb for naming our service object
RULES FOR SERVICE OBJECT
• use instance methods, not class methods
• there should be very few public methods
• method should return rich objects and not boolean
• dependent service objects should be created inside the
initialize or lazily
• during the initialize, declare each options as variable instance
CODE LIKE PATTERN HUNTER
• basically refactoring consists of finding repetitive code and place it
in a dedicated method
• in POO, you refactor class with code patterns
• don’t look for how to refactor a class, it will remains incomplete.
Look for patterns instead and refactor to make the pattern
consistent in the implementation
• A class should have only one reason to change and only one - Gang
of Four.
LIST OF PATTERNS
• Template pattern
• Adapter pattern
• Factory pattern
• Builder pattern
• State pattern
• Proxy pattern
LINKS
• https://www.viget.com/articles/slimming-down-your-models-and-controllers
• http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
• https://richonrails.com/articles/rails-4-code-concerns-in-active-record-models
• https://launchschool.com/blog/understanding-polymorphic-associations-in-rails
• https://www.instacart.com/opensource
• https://github.com/instacart/amountable
• http://multithreaded.stitchfix.com/blog/2015/06/02/anatomy-of-service-objects-in-rails/
• SUGAR : https://www.thc.org/root/phun/unmaintain.html

Code refactor strategy part #1

  • 1.
    CODE REFACTOR STRATEGY byTracyLOISEL, Lead Developer at monAlbumPhoto.fr Geneva, september the 28th
  • 2.
    THANKS • Many thanksto Geneva Ruby Brigade, the geneva ruby on rails developers group • Many thanks to monAlbumPhoto.fr to let me share with you our experience
  • 3.
    WHY CODE REFACTOR? • to code faster next time and not by monkey patching • to debug easier next time without hurting yourself • to build sustainable code with services oriented architecture
  • 4.
    AND WHY A STRATEGYFORTHAT ? • to be far beyond esthetic matters and keep developers in peace • to share a same behave while refactoring with team-mates • to let all your developers take part of the project, no matter if they feel confident enough to refactor code from other developers
  • 5.
    THE CONTEXT ATMAP • monAlbumPhoto is one the main photos printing services in France • the company started at 2004 and has been acquired by M6 Group in 2010 • it is one the main Ruby on Rails project in Europe said Jean-DanielVouille, CTO at famous Echos newsgroup • 20 developpers work in Paris for the IT department under the management of our CTO Benjamin Grelié, while we outsource also in Russia and India • the service is powered by a google cloud architecture with above 20 production servers • we have a factory of 5000 squared meters in Picardie (France)
  • 6.
    THREE MORE WAYS TODON’T REPEAT EACH OTHER
  • 7.
    MODEL CONCERNS • concernslet you share code between models • think about an email validation regexp. In a single app many model would include an email_address attributes • standardize its validation inside a concern
  • 9.
    CONTROLLER CONCERNS • concernslet you share code between controllers too • like constants or methods called within before_filter
  • 11.
  • 12.
    POLYMORPHIC MODEL • thinkabout price information, in a single app you could have many objects with price attributes because they are billable • now think about the mess if each developer design his own price for his current model ? how many files 2 or 3 years after ?
  • 13.
    POLYMORPHIC MODEL • polymorphicmodel and concern are a solution to manage a kind of information that is use elsewhere with not necessary variations (cost vs value, amount vs total, etc) • standardize implementation of an information with a polymorphic model
  • 15.
  • 16.
    THE BEGINNING • Forlong term, with developers coming then leaving, we want to make monkey patch an irregular way to code • We want to slim down our controllers and models. Concerns failed to do it in long terms, it’s not enough • We want to know instantly where a function is located. No more magic calls and methods that make too much, even the coffee.
  • 17.
    OUR SPLITS • /app/modelsis for relations, validations, search strategy and other strategy definition • /app/controllers is to accept HTTP requests and respond with data • /app/models/concerns is to share code between models • /app/models/concerns is to share code between controllers • /app/services is for Service Object that accept input, perform works and return result • /app/supports is to extend ActiveRecord::Base with a service object
  • 18.
    NAMING CONVENTIONS • Eachconcern name is appended with ableConcern term like in AmountableConcern • Each module support name is appended with Support term like in CloningSupport • Each service object name is appended with Service term like in UserAddressesService and is prefixed with Active term when it play for a single model like in ActiveFeedService • We avoid verb for naming our service object
  • 19.
    RULES FOR SERVICEOBJECT • use instance methods, not class methods • there should be very few public methods • method should return rich objects and not boolean • dependent service objects should be created inside the initialize or lazily • during the initialize, declare each options as variable instance
  • 20.
    CODE LIKE PATTERNHUNTER • basically refactoring consists of finding repetitive code and place it in a dedicated method • in POO, you refactor class with code patterns • don’t look for how to refactor a class, it will remains incomplete. Look for patterns instead and refactor to make the pattern consistent in the implementation • A class should have only one reason to change and only one - Gang of Four.
  • 21.
    LIST OF PATTERNS •Template pattern • Adapter pattern • Factory pattern • Builder pattern • State pattern • Proxy pattern
  • 22.
    LINKS • https://www.viget.com/articles/slimming-down-your-models-and-controllers • http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/ •https://richonrails.com/articles/rails-4-code-concerns-in-active-record-models • https://launchschool.com/blog/understanding-polymorphic-associations-in-rails • https://www.instacart.com/opensource • https://github.com/instacart/amountable • http://multithreaded.stitchfix.com/blog/2015/06/02/anatomy-of-service-objects-in-rails/ • SUGAR : https://www.thc.org/root/phun/unmaintain.html