Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DDD & DSL in Ruby

DDD & DSL in Ruby

DDD & DSL in Ruby. WeBukovel 2015

Volodymyr Melnyk

March 01, 2015
Tweet

More Decks by Volodymyr Melnyk

Other Decks in Programming

Transcript

  1. Base Application Layers • Presentation Layer / User Interface •

    Application Layer • Domain Layer / Model Layer • Infrastructure Layer
  2. Some facts about DDD • It’s really awesome for moderately

    or very complicated projects. • It’s not about patterns, it’s more like a part of Agile development framework. • It’s hard to start using.
  3. Ubiquitous Language • Do not reinvent terms. Use existing ones.

    • All team members and customers should use the same language/dictionary. • Build Domain Model on top of the Ubiquitous Language.
  4. Domain Model • Domain Model describes business entities and their

    relations. • Build a Domain Model inside the team using smart people from customer side. • Use all available tools for this. UML is good for this purpose.
  5. Deep Inside Refactoring • Also known as a Domain Model

    refactoring. • Improve your Domain Model all the time. • Get contributions from domain experts all the time.
  6. Entity • An Entity is a something mutable and existing

    in time. • An Entity has properties and behaviour. • Entity is where OO rules.
  7. Value Object • In most cases it’s a wrapper around

    a core type, like Fixnum, String, etc. • It incapsulates some additional logic around core types. • It represents some properties of an Entity.
  8. Service • It’s also known as Interactor. • It performs

    some complicated action which affects two or more Entities. • Of course, it implements actions in terms of Domain Model.
  9. Aggregate • Used to aggregate high- coupled entities around the

    main one called Root. • Describes dependencies between Entities. • Allows to hide less important Entities.
  10. Factory • It incapsulates some complex logic of creation of

    Entities and their binding. • Actually all creational GoF patterns are some kind of Factories (not only Abstract Factory or Factory method).
  11. Repository • It is an abstraction over data storage. •

    It provides logic to retrieve certain data and additional logic like caching. • Basically in Rails Active Record models are Repositories.
  12. Active Record • It’s really awesome for development of a

    blog in 15 minutes. • It’s really hard and painful to develop projects with complex logic. • It maps tables to models and that’s cool. • … but here comes Leak of Abstraction for complex queries.
  13. Arguments against STI • In most cases composition is preferable

    over inheritance. • In ALL cases STI means: I do not know domain. • STI is not about simplification. In future you will get problems.
  14. Arguments against polymorphic associations Polymorphic associations are turned inside out

    STI, so all arguments against STI are correct for polymorphic associations.
  15. Data Mapper • It forces you to write more code.

    • … but it’s more flexible, because it allows you to use composition easily.
  16. …or, maybe do not use ORMs at all • It’s

    a simple declarative language. • It’s very fast. • Actually ORMs do not allow you to really abstract from the DB. • The only real flaw is that you should develop your own Data Access Layer.
  17. Purposes of DSL • It makes code more declarative: write

    what to do, not how to do it. • It allows you to use code as a documentation. • It allows you to write code which a domain specialist can read, understand and approve easily.
  18. Existing DSL-like tools in Ruby ecosystem • BDD frameworks like

    Spec, Cucumber • Rails routing and associations • Some RESTful frameworks, like Sinatra, Cuba, etc. • Deploying/automation tools, like Capistrano, Chef, etc.
  19. Why Ruby is so good for DSL? • Blocks of

    code • Eval-methods (eval, instance_eval, class_eval, module_eval, module_exec, class_exec, instance_exec) • Proc-objects (procedure, lambda)
  20. Example of RSpec’s DSL RSpec.describe Fixnum do describe ‘#odd?’ do

    context ‘when the subject is an odd number’ do it ‘returns true’ do expect(1.odd?).to eq true end end context ‘when the subject is an even number’ do it ‘returns false’ do expect(2.odd?).to eq false end end end end
  21. My current project • Adapters for SOAP APIs • Our

    gems are wrappers over Savon gem. • Class per Service • Method redefinition in children’s Service classes. (WTF?!) • It's not possible to decorate input/output and handle exceptions raised from the API side.
  22. Result clients = ClientMap.define do client_for :some_service do uses_wsdl ‘http://some_url.com/api?wsdl’

    uses_namespaces({ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' }) handles SoapFault, with: :return_fake_response decorates requests: [:get, :send], with: :some_decorator decorates responses: [:get, :send], with: :some_another_decorator end end
  23. clients = ClientMap.define do client_for :some_service do uses_wsdl ‘http://some_url.com/api?wsdl’ uses_namespaces({

    'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' }) handles SoapFault, with: :return_fake_response decorates requests: [:get, :send], with: :some_decorator decorates responses: [:get, :send], with: :some_another_decorator end end
  24. DDD through DSL • DDD does not force you to

    use DSL, but subtly suggests using it. • DSL allows you to bind entities easily. • DSL is pretty awesome for creating configurations.
  25. DSL-Driven Development • Create a Domain model • Create an

    example of DSL on paper • Implement main Entities • Implement DSL and create functional tests on it.
  26. Conclusions • DDD is awesome for projects with moderate or

    high complexity of the domain model. • DSL is unconditionally awesome. • Rails is awesome for prototyping. • Use DDD with DSL together to get maximum benefit.