build and maintain large Ruby
applications
Enrico Teotti - @agenteo - http://teotti.com
enrico.teotti@gmail.com
build and maintain large Ruby
applications
Enrico Teotti - @agenteo - http://teotti.com
enrico.teotti@gmail.com
Ruby files in a project
are ingredients in a recipe
think the application you’re working on
yeast honeysalt
milk
flourwater
lard
sugar
arugula
squacqueroneprosciutto
yeast honeysalt
milk
flourwater
lard
sugar
arugula
squacqueroneprosciutto piadina
3 months later
yeast honeysalt
milk
flourwater
lard
sugar
arugula
squacqueroneprosciutto piadina
the curse of
knowledge
6 months later
yeast
honeysalt
milk
flourwater
lard
sugar
arugula
squacqueroneprosciutto
biscuits
mozzarella
sunflower oil
carrots
eggstomato puree
basil
oregano
mascarpone
yeast
honeysalt
milk
flourwater
lard
sugar
arugula
squacqueroneprosciutto
biscuits
mozzarella
sunflower oil
carrots
eggstomato puree
basil
oregano
mascarpone
piadina
pizza margherita
tiramisu
carrot cake
in Italy everybody groups
ingredients… by colour
white ingredients
green ingredients
red ingredients
white ingredients
green ingredients
classes grouped
by design pattern
ls -l app/
controllers
helpers
models
presenters
services
serializers
strategies
utils
views
http://teotti.com/application-directories-named-as-architectural-patterns-antipattern/
piadina
pizza margherita
tiramisu
carrot cake
namespaces
module Promotions
class NewMember
private
def fetch_member(id)
Membership::Finder.new(id)
end
end
end
module Blog
class AfterPublish
private
def add_blogger_to_promotion
Promotions::NewMember.new
end
end
end
main Ruby application
promotions
room
decorator
name finderblog membership
“If a developer must consider the implementation of a
component in order to use it, the value of
encapsulation is lost.” Eric Evans
piadina worktop
tiramisu worktop
shared worktop
carrot cake worktop
pizza worktop
piadina worktop
shared worktop
dessert worktop
pizza worktop
gems
Ruby libraries
A
C
D
B
E
main Ruby application
your health plan
API
drug information
claims platform
product
information
membership
Conway’s Law
“organizations which design systems … are
constrained to produce designs which are
copies of the communication structures of
these organizations"
gem
gem
gem
gem
gem
dependency
dependency
dependency
dependency dependency
http://teotti.com/create-dependency-structures-with-local-ruby-gems/
$ cd local_gems
$ bundle gem claims_platform
$ bundle gem membership
$ bundle gem product_information
$ vim claims_platform/claims_platform.gemspec
Gem::Specification.new do |s|
s.name = 'claims_platform'
s.add_runtime_dependency 'membership'
s.add_runtime_dependency 'product_information'
end
$ cat local_gems/claims_platform/Gemfile
source 'https://rubygems.org'
path '..'
gemspec
directory where all local gems live$ mkdir local_gems
A
C
D
B
E
main Ruby application
your health plan
API
drug information
claims platform
product
information
membership
Sinatra, Rails, Lotus
A
C
D
B
E
main Ruby application
your health plan
API
drug information
claims platform
product
information
membership
unit tested
unit tested
unit testedunit tested
unit tested
A
C
main Ruby application
B
using C
behaviour
without
requiring it
When you execute A
behaviour from the main
application first,
triggering B (which is
using C without
depending on it) will not
trigger an error.
When you trigger B
(using C without
depending on it) from
the main application will
not trigger an error
loaded in memory, deamon or webserver
unit tested
unit tested
not unit tested
A
C
D
B
E
main Ruby application
F
H
I L
membership
payment API
payment
platform
bank
transaction
credit card
transaction
your health plan
API
drug information
claims platform
product
information
membership
A
C
D
B
E
main Ruby application
F
H
I L
membership
payment API
payment
platform
bank
transaction
credit card
transaction
your health plan
API
drug information
claims platform
product
information
membership
A
C
D
B
E
main Ruby application
F
H
I L
membership
payment API
payment
platform
bank
transaction
credit card
transaction
your health plan
API
drug information
claims platform
product
information
membership
main Ruby application
your health
plan API
drug
information
claims
platform
product
information
membership
membership
payment
API
payment
platform
bank
transaction
credit card
transaction
deploy parts of a Rails app
EDITORIAL UI PUBLIC UI
DOMAIN LOGIC
editorial_ui.gemspec public_ui.gemspec
domain_logic.gemspec
Rails web application
deploy@publicServer $ RUNNING_MODE=public rails s
deploy@editorialServer $ RUNNING_MODE=admin rails s
http://teotti.com/deploy-parts-of-a-ruby-on-rails-application/
http://teotti.com/reduce-memory-footprint-requiring-portions-of-your-component-based-rails-applications/
Rails.application.routes.draw do
case AppRunningMode.value
when :admin
mount AdminUi::Engine => "/admin"
when :public
mount PublicUi::Engine => "/"
else
mount AdminUi::Engine => "/admin"
mount PublicUi::Engine => "/"
end
EDITORIAL UI LEGACY MIGRATIONPUBLIC UI
DOMAIN LOGIC
editorial_ui.gemspec public_ui.gemspec
domain_logic.gemspec
Rails web application
legacy_migration.gemspec
lotus.rb
legacy Ruby applications
It is not age that turns a piece of software into a
legacy system, but the rate at which it has been
developed and adapted without having been
reengineered.
Picasso
BOOKING
PAYMENT
TRIP
tentative
reservation
booked
reservation
completed
trip
reservation
charged
Picasso
incremental re-engineering
• Decompose the legacy system into parts.
• Choose one part to tackle at a time.
• Put tests in place for that part and the parts that depend on it.
• Take appropriate steps to wrap, reengineer, or replace the legacy component.
• Deploy the updated component and obtain feedback.
• Iterate
incremental re-engineering
• Decompose the legacy system into parts.
• Choose one part to tackle at a time.
• Put tests in place for that part and the parts that depend on it.
• Take appropriate steps to wrap, reengineer, or replace the legacy component.
• Deploy the updated component and obtain feedback.
• Iterate
incremental re-engineering
• Decompose the legacy system into parts.
• Choose one part to tackle at a time.
• Put tests in place for that part and the parts that depend on it.
• Take appropriate steps to wrap, reengineer, or replace the legacy component.
• Deploy the updated component and obtain feedback.
• Iterate
http://teotti.com/reengineer-legacy-rails-applications/
team mindsets
fixed mindset growth mindset
team mindsets
* the person is so talented

* the person is so smart

* the person is a CSS ninja
* the person is experienced

* the person works really hard

* the person is passionate about CSS and keeping up to date
–Norman Kerth
“Regardless of what we discover, we understand and truly believe
that everyone did the best job they could, given what they knew
at the time, their skills and abilities, the resources available, and
the situation at hand.”
build and maintain large Ruby
applications
Enrico Teotti - @agenteo - http://teotti.com
enrico.teotti@gmail.com

Build and maintain large Ruby apps 0.0.1