build and maintain large ruby apps 0.0.1

Post on 21-Feb-2017

173 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

milkflourwater

lard

sugar

arugula

squacqueroneprosciutto

yeast honeysalt

milkflourwater

lard

sugar

arugula

squacqueroneprosciutto piadina

3 months later

yeast honeysalt

milkflourwater

lard

sugar

arugula

squacqueroneprosciutto piadina

the curse of knowledge

6 months later

yeast

honeysalt

milkflourwater

lard

sugar

arugula

squacqueroneprosciutto

biscuits

mozzarella

sunflower oil

carrots

eggstomato puree

basil

oregano

mascarpone

yeast

honeysalt

milkflourwater

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 ingredientsgreen ingredients

red ingredients

white ingredientsgreen 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 endend

module Blog class AfterPublish private def add_blogger_to_promotion Promotions::NewMember.new end endend

main Ruby application

promotions room decoratorname 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

gemsRuby 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

dependencydependency

dependencydependency 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.gemspecGem::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/Gemfilesource '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

APIpayment 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 docase 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

top related