From legacy to DDD@andrzejkrzywda
Arkency
Did you write any code today?
Are you proud of it?
Why?(do you think that surgeons are proud of their work?)
What is legacy code?Ruby is much more unified here than PHP
Any Rails code is legacy code
Legacy
• Frameworks
• monolithic
• no architecture
• no tests
Strategic vs Tactical DDD
Tactical DDD• entity
• value objects
• aggregate
• domain event
• services
• repositories
• factory
DDD-lite• app service
• domain service
• load aggregate from the repo
• do sth cool
• may use some value objects
• may trigger some domain events
• save aggregate (repo)
Strategic DDD
• bounded contexts
• context map
http://martinfowler.com/bliki/BoundedContext.html
Software House management tool
as microservices partially available
different persistencedata duplication
Context MapHR Project Management Finances
Invoicing
CRUD
DDD-lite
external SaaS
Communication
developer project client
How to get there from legacy?
BTW, There’s no such thing as the ultimate DDD codebase
Draw the Context Mapthe only thing to remember from this talk
Ongoing processNo time for 2-months rewrites
Peopleware the human factor
http://andrzejonsoftware.blogspot.com/2014/01/refactoring-human-factor.html
Escape from the CRUD verbsTalk more to the business people
Test coverage
#noregressions
when you’re a client you don’t like them too
Mutation testing is the real test coverage!
http://blog.arkency.com/2015/04/why-i-want-to-introduce-mutation-testing-to-the-rails-event-store-gem/
http://blog.arkency.com/2015/06/how-good-are-your-ruby-tests-testing-your-tests-with-mutant/
mutation testing php - humbug
https://github.com/padraic/humbug
Test units, not classes!http://andrzejonsoftware.blogspot.com/2015/02/tdding-unit-not-class.html
http://andrzejonsoftware.blogspot.com/2014/04/tdd-and-rails-what-makes-good-unit.html
http://blog.arkency.com/2014/09/unit-tests-vs-class-tests/
Escape from the framework ASAP
http://blog.arkency.com/2015/03/extract-a-service-object-in-any-framework/
Call application services from the framework
Active Record doesn’t make your code happy
AR is not DDD-lite-friendlyData Mapper is better here
Don’t just pass the params/hash everywherehttp://andrzejonsoftware.blogspot.com/2011/12/args-opts-params.html
Wrap your legacy contexts with the
application services layer
Use events to communicate between
bounded contextsrails_event_store
Separate reads/writes at the services layer
CQRS
Eliminate querying from BC to another
Push the data!
Keep the Bounded Contexts in-sync by publishing all the
important events
Easier testing when no dependency on other
system
Read modelsDenormalized data
Treat your frontend as a separate Bounded
Context
When in doubt, think in aggregates
Event sourcingbuild your aggregates from events
audit log for free(no, it’s not slow, but thanks for asking)
Distributed transactions are tricky
Easier setup of the project when it’s a smaller
pieceUseful when you’re maintaining many projects and need to bugfix them from time to time
https://laracasts.com/discuss/channels/general-discussion/folder-and-namespace-structure-with-ddd/replies/17753
Legacy -> DDD books
• red book, Vaughn Vernon
• blue book, Eric Evans
• Refactoring, Fowler
• Legacy code, Feathers
THANKS!(go draw your context maps now)