Domain Driven Rails

0a5b413991ed9a58bb8845f7ecab7106?s=47 Yan Pritzker
September 04, 2014

Domain Driven Rails

Some of the patterns used while building Reverb.com's large codebase including concepts from DCI and Clean Architecture such as Use Cases, Roles, Events, and Policies.

0a5b413991ed9a58bb8845f7ecab7106?s=128

Yan Pritzker

September 04, 2014
Tweet

Transcript

  1. 2.
  2. 3.
  3. 19.

    @skwp @reverbdotcom #wcr14 http://martinfowler.com/articles/distributed-objects- microservices.html “I'm wary of distribution and

    
 my default inclination is to prefer a monolithic design” “While small microservices are certainly simpler to reason about, I worry that this pushes complexity into the interconnections between services” “Refactoring becomes much harder when you have to do it across remote boundaries.”
  4. 24.

    @skwp @reverbdotcom #wcr14 Product
 400 LOC
 ~150 LOC non-ActiveRecord Churn:

    49 changes this year" Order
 333 LOC
 ~200 LOC non-ActiveRecord Churn: 36 changes this year User
 338 LOC
 ~200 LOC non-ActiveRecord Churn: 29 changes this year
  5. 28.
  6. 29.

    @skwp @reverbdotcom #wcr14 Don’t put different rates of change together"

    Kent Beck - Smalltalk Best Practice Patterns Data Model Business Logic
  7. 30.

    @skwp @reverbdotcom #wcr14 Separate 
 what the system is "

    from what the system does" James Copelien & Trygve Reenskaug (Data, Context, Interaction)
  8. 38.

    @skwp @reverbdotcom #wcr14 “Active Record is a good choice for

    domain logic that isn't too complex, such as creates, reads, updates, and deletes” Martin Fowler
  9. 39.

    @skwp @reverbdotcom #wcr14 If Controller and Model are all you

    have then 
 one has to be skinny and one has to be fat
  10. 40.

    @skwp @reverbdotcom #wcr14 Domain Layer skinny framework, 
 healthy business

    logic," no fat anywhere http://joncairns.com/2013/04/fat-model- skinny-controller-is-a-load-of-rubbish/
  11. 41.

    Model Controller View The Rails Way The Way Active Record

    Use Cases Grape API Controllers Cron Redis Rake HTTP Services Workers R Entities Roles DB Listeners Events
  12. 53.

    @skwp @reverbdotcom #wcr14 User.where(…) User.active User.find(1) This is easy to

    replace with
 something other than AR. 
 Repository not required. Don’t leak SQL outside of AR
  13. 81.

    @skwp @reverbdotcom #wcr14 Methods related to each" other but loosely

    related" to the parent concept" and used only in a few" Use Cases
  14. 88.
  15. 92.

    @skwp @reverbdotcom #wcr14 Global listeners for cross-cutting concerns
 without littering

    code Wisper::GlobalListeners.add(Reverb::Listeners::AnalyticsListener.new)"
  16. 97.

    @skwp @reverbdotcom #wcr14 Injectable, but has a default Simple code,

    only need to test one path
 for the imperative side effect" (sending an email)
  17. 104.

    @skwp @reverbdotcom #wcr14 Active Record Use Cases Grape API Controllers

    Cron Redis Rake HTTP Services Workers R Entities Roles DB Listeners Events Active Record Use Cases Grape API Controllers Cron Redis Rake HTTP Services Workers R Entities Roles DB Listeners Events
  18. 106.