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

Domain-Driven Design heuristics for dealing with legacy software @ Techorama 2022

Domain-Driven Design heuristics for dealing with legacy software @ Techorama 2022

How can we get better as software designers? By becoming more aware of our design heuristics and being intentional as we cultivate and refine them. Heuristics aid in the design and even determine our attitude and behaviour. We each have our own (often implicit) heuristics acquired through reading, practice, and experience, especially when surrounded by legacy software. Let us share these heuristics during a modelling session! In this session, I'll present you with a legacy modelling problem, which I will show you how we can solve with DDD legacy patterns. I will explain the four strategies for getting started with DDD when you have a big commitment to legacy systems by Eric Evans. To really understand the strategy, I will explain the bounded context pattern and show you how you can implement the strategy in your architecture. Finally, I will share some personal heuristics when dealing with legacy software. You will leave this session with shared knowledge from experience in dealing with legacy software and how you can start Context mapping for strategic Domain-Driven Design patterns while surrounded by legacy!

Kenny Baas-Schwegler

October 11, 2022
Tweet

More Decks by Kenny Baas-Schwegler

Other Decks in Programming

Transcript

  1. @kenny_baas No I won’t rant a lot about “The next

    internet explorer type microsoft legacy for generations to come”
  2. @kenny_baas “anything that provides a plausible aid or direction in

    the solution of a problem but is in the final analysis unjustified, incapable of justification, and potentially fallible. – Billy Vaughn Koen - Nuclear Engineer Heuristic https://wirfs-brock.com/blog/2019/03/20/growing-your-personal-design-heuristics/
  3. @kenny_baas Photo by Evan Qu on Unsplash Design heuristic “Favour

    monolithic architecture over microservices architecture”
  4. @kenny_baas Photo by Christopher Burns on Unsplash But…But I thought

    we should get rid of Legacy software, not create more?
  5. @kenny_baas Legacy software In computing, a legacy system is an

    old method, technology, computer system, or application program/code, "of, relating to, or being a previous or outdated computer system," yet still in use. https://en.wikipedia.org/wiki/Legacy_system
  6. @kenny_baas Monolithic architecture A single-tiered software application in which different

    components combined into a single program form a single deployable unit. It can be a MVC approach or an API with a database.
  7. @kenny_baas To communicate effectively, the code must be based on

    the same language used to write the requirements - the same language that the developers speak with each other and with domain experts - Eric Evans
  8. @kenny_baas We all know or should know that language is

    fluid, liquid, subject to the whims of the people. Language evolves, as it should. Because language changes to accommodate new users, the older users resist and complain. http://tednellen.blogspot.com/2013/04/language-is-fluid.html
  9. @kenny_baas It is not the domain experts knowledge that goes

    to production, it is the assumption of the developers that goes to production - Alberto Brandolini
  10. @kenny_baas A straight line between 2 points corresponds to a

    compass direction in reality.. • Except for points located in Greenland • Except for points located in Africa
  11. @kenny_baas A model is a simplified representation of a thing

    or phenomenon that intentionally emphasizes certain aspects while ignoring others. Abstraction with a specific use in mind. — Rebecca Wirfs-Brock
  12. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic Start

    communicating business change in contextual boundaries that form the bounded context (purpose, need, responsibility)
  13. @kenny_baas Photo by Evan Qu on Unsplash Design heuristic When

    designing new bounded contexts, they should have one team who is owning that bounded context. A team can have multiple bounded context
  14. @kenny_baas Photo by Gloria Cretu on Unsplash Recap • A

    legacy system is an old application program/code still in use. • Monolith is a deployment strategy. • Legacy != Monolith, and most legacy software is build as monoliths • Most monoliths components are not designed in a DDD way, creating a disconnect with the business strategy and creating a big ball of mud.
  15. @kenny_baas Photo by Felix Mooneeram on Unsplash BigScreen • Fictitious

    company • International cinema chain with 80 cinema’s located in 12 different countries • Custom software system • The current system is completely entangled, a big ball of mud (BBoM) that has been around for many years
  16. @kenny_baas Big Ball of Mud Software system that lacks a

    perceivable architecture and the model is implicit.
  17. @kenny_baas Requirements • Reopen in approx 2-3 months • 1.5

    meters apart from reservations • Sign a health check • Able to go back when needed
  18. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic Discover

    and identify bounded context with EventStorming
  19. @kenny_baas Photo by Evan Qu on Unsplash Design heuristics •

    Split according to the language. • Split according to the departments. • Split according to the users.
  20. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic Pick

    some boundaries to start with and iterate.
  21. @kenny_baas Using collaborative modelling to build a shared understanding of

    your domain and use it to guide your design _is_ the philosophy behind DDD though. The rest is principles, patterns, and practices. — Mathias Verraes https://verraes.net/2021/09/what-is-domain-driven-design-ddd/
  22. @kenny_baas Requirements • Reopen in approx 2-3 months • 1.5

    meters apart from reservations • Sign a health check • Able to go back when needed
  23. @kenny_baas 3 Strategies + Evolution 1. Bubble context 2. Autonomous

    bubble 3. Exposing Legacy as a service (LaaS) ➔ Expanding a bubble https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf
  24. @kenny_baas Anti-corruption Layer (ACL) Translation layers can be simple, even

    elegant, when bridging well-designed bounded contexts with cooperative teams. But when control or communication is not adequate to pull off a shared kernel, partner or customer/supplier relationship, translation becomes more complex. The translation layer takes on a more defensive tone. Therefore: As a downstream client, create an isolating layer to provide your system with functionality of the upstream system in terms of your own domain model. This layer talks to the other system through its existing interface, requiring little or no modification to the other system. Internally, the layer translates in one or both directions as necessary between the two models. ACL is more than a Translation Layer! From: https://www.domainlanguage.com/ddd/reference/ https://virtualddd.com/sessions/20
  25. @kenny_baas Repositories For each type of aggregate that needs global

    access, create a service that can provide the illusion of an in-memory collection of all objects of that aggregate’s root type. Set up access through a well-known global interface. Provide methods to add and remove objects, which will encapsulate the actual insertion or removal of data in the data store. public interface AuditoriumSeatings { Task<AuditoriumSeating > GetAuditoriumSeating (ShowId showId); }
  26. @kenny_baas public class AuditoriumSeatingAdapter : AuditoriumSeatings { private readonly IProvideAuditoriumLayouts

    _auditoriumSeatingRepository ; private readonly IProvideCurrentReservations _reservationsProvider ; public AuditoriumSeatingAdapter (IProvideAuditoriumLayouts auditoriumSeatingRepository , IProvideCurrentReservations reservationsProvider ) { _auditoriumSeatingRepository = auditoriumSeatingRepository ; _reservationsProvider = reservationsProvider ; } public async Task<AuditoriumSeating > GetAuditoriumSeating (ShowId showId) { var auditoriumDto = await _auditoriumSeatingRepository .GetAuditoriumSeatingFor (showId.Id); var reservedSeatsDto = await _reservationsProvider .GetReservedSeats (showId.Id); return AdaptAuditoriumSeatingDto(auditoriumDto, reservedSeatsDto ); } private static AuditoriumSeating AdaptAuditoriumSeatingDto(AuditoriumDto auditoriumDto, ReservedSeatsDto reservedSeatsDto ) { var rows = new Dictionary<string, Row>(); foreach (var (rowName, seatDtos) in auditoriumDto.Rows) { ………………
  27. @kenny_baas Ports and Adapters The hexagonal architecture, or ports and

    adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.
  28. @kenny_baas Photo by Evan Qu on Unsplash Design heuristic (repeated)

    “Favour monolithic architecture over microservices architecture”
  29. @kenny_baas Photo by Evan Qu on Unsplash Design heuristics (Competing)

    1. “Integrate through an API on application layer” 2. “Integrate through an API on the database layer”
  30. @kenny_baas 3 Strategies + Evolution 1. Bubble context 2. Autonomous

    bubble 3. Exposing Legacy as a service (LaaS) ➔ Expanding a bubble https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf
  31. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic “Either

    remove a bubble context, or dedicate resources and people to move towards an autonomous bubble context”
  32. @kenny_baas Photo by Yong Chuan Tan on Unsplash Black hole

    anti-pattern When a POC is put to production and not getting the time and people to decouple, making the bubble burst and be absorbed back by the Big Ball of Mud
  33. @kenny_baas Photo by Evan Qu on Unsplash Value heuristic “Use

    Test-Driven Development and good unit testing practices to get fast feedback, and become more confident on changes”
  34. @kenny_baas 3 Strategies + Evolution 1. Bubble context 2. Autonomous

    bubble 3. Exposing Legacy as a service (LaaS) ➔ Expanding a bubble https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf
  35. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic “Don’t

    rebuild functionality that works as intended and has no or little expected changes coming up. (Including software characteristics)”
  36. @kenny_baas Photo by Evan Qu on Unsplash Guiding heuristic “You

    can use Monolith and Microservices architecture together!!”
  37. @kenny_baas 3 Strategies + Evolution 1. Bubble context 2. Autonomous

    bubble 3. Exposing Legacy as a service (LaaS) ➔ Expanding a bubble https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf
  38. @kenny_baas Photo by Evan Qu on Unsplash Design heuristic “Implement

    requirements and information based on the responsibility of your bounded context”
  39. @kenny_baas 3 Strategies + Evolution 1. Bubble context 2. Autonomous

    bubble 3. Exposing Legacy as a service (LaaS) ➔ Expanding a bubble https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf
  40. @kenny_baas Photo by David Ramírez on Unsplash “Every tradeoff we

    make, that we might see as technical has also user and biz effects and are hence a sociotechnical tradeoff” – Ruth Malan / @ruthmalan
  41. @kenny_baas Photo by Gabriella Clare Marino on Unsplash “Our problems

    are not legacy software systems, these can be easily changed giving enough time and people. Our problem is we are dealing with legacy sociotechnical system, who have legacy best practices competing with emerging practices”