Code refactor strategy part #1

Post on 25-Jan-2017

67 views 3 download

transcript

CODE REFACTOR STRATEGYby Tracy 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 FOR THAT ?

• 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-Daniel Vouille, 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 WAYSTO 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