Está en la página 1de 2

Big Ball of Mud

Kitchen Sink
Kerfuffle
We all know rails
1. its great because it is so fast and easy
> rails new sweet_webapp # ship it!
- simple, well known architectural pattern (MCV)
- gems and plugins for everything (devise, etc.)
- global access to every object in your system, so you never have to worry a
bout loading or dependencies
=> This is an excellent pattern for quickly serving and persisting simple we
b forms in a database

2. but then it starts to slow down... each of those strengths come with a long
shadow
- MVC -> Big Ball of Mud
- gems/plugins -> Kitchen Sink
impossible to update dependancies, tied hands because gen
eric solution no longer severs needs (monkey
patch / extend the gem "make it work"), slow tests bc dom
ain logic is tied to your gems (active
record), large memory footprint
- global access -> Kerfuffle - fragile, frightening, code

3. Why does this happen?
MVC -> BBM
- Violates core OO principals: Encapsulation, Knowledge hiding, Stable Dep
endency Ordering
- Violation of DIP, Demeter, and Ask Don't tell
- DIP
DBSchema -> Model -> Controller -> View
- assets: DRY, convention over configuration (great for simple
form persistence - no domain logic)
- liabilities: Changes to any lower layer ripple through higher laye
rs (shotgun surgery),
Out of control dependency graph
Hides your Domain Logic:
Domain logic is mixed with Service logic (ActiveRecor
d / Models, Controllers [if save then...]),
Domain logic is hidden in Service logic (AR: validati
ons, callbacks, save if; AC: before filters)
Domain itself is hidden in the Framework (person.acco
unt.houses.first.bridge)
Domain logic obscured framework life cycles (AR: afte
r_find)
=> 1. Changes to or in Services / Frameworks ripple
through your app (non-trival to upgrade
rails) - shotgun surgery -- check for other smell
s
2. It is hard to know what the application is (st
ill) supposed to do
- long "spin up time" (recurring payment)
- low "bus number" (why is it this way)
- fear (we don't know what happens if we change
this)
- code silos / ownership
3. Domain Functionality is limited by technologie
s du jour -- adoption of new technology can
be very difficult (imagine removing Active Rec
ord and Mysql to switch to Mongoid/Mongo)
- Demeter
AR: Global access, wide (almost infinite) interface for objects, can b
e performance penalty for acting otherwise
- assets: Fast to code, easy to think of at the moment, fewer fi
les / classes (not really a benefit)
- liabilities: Relationships in Domain are exposed and repeated every
where (not DRY),
Global access encourages us to add responsibilities to
existing objects rather than creating new
ones
- this ties the app together, key to implementing BB
M
- changing how an object is stored can break your ap
plication
- entity relations are repeated all over the app,
sometimes silently depended on
- product.cart.customer.address means that a custome
r cannot have two carts -- ever.
- Ask Dont Tell
AR: Global access, auto-magic ? methods, confusion persistence mechani
sm with behavior (latch has the state i want)
- assets: Fast to code, easy to think of at the moment, fewer fil
es / classes (not really a benefit)
- liabilities: spreads decision logic over n+1 objects where n objects
are needed to make the decision
- eg. door.open! vs. door.open! if door.latch.is_close
d? (usually violation of LOD too)
- obscures logic, ties app together

- in fact, it violates all SOLID principals: SRP, Open/Close, Interface
segregation, Liskov, DIP

4. What can we do about it?
1. Order Dependencies Stably
- hexagonal
- DIP layers
2. Separate Domain from dependencies:
- Skinny Controller, Skinny Model, Smart PORO
3. Limit access
- physical separation
- Folders / namespaces in app/models, app/controllers, and /lib
- Unbuilt gems
- in rails project
- out of rails project
- Built gems
- used across your enterprise
- Tell Demeter to Obey
4. Use gems/plugins sparingly and limit where you use them
- may be worth creating an adapter or an application service (Resque / S
idekiq)

También podría gustarte