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

Disentangling legacy software approached with Domain-Driven Design @ Techorama 2023

Disentangling legacy software approached with Domain-Driven Design @ Techorama 2023

If one thing unites us as software developers, it must be legacy software. Almost and perhaps everyone in their career will deal with them. Almost everyone I talk to does not like to work on legacy software because legacy software is considered to be outdated and hard-to-change technology. It is hard to change because we do not understand how they work, it is usually not documented, and no proper unit tests exist. Making a small refactor can make the system implode and frustrate us. Wishing we could just write new software with the latest technology as the cool kids do! Another problem is businesses also don’t usually want to invest in changing the system, they are more interested in delivering new functionality. It is providing value, after all! What if you can keep the business running and move away from that legacy?

In this talk, I will provide my set of design heuristics distilled from my experience working with legacy systems. An important aspect of the work I did with the legacy system was approaching the software design with Domain-Driven Design and the legacy strategic patterns described by Eric Evans. I will provide real-life examples of how I and the teams used these patterns to move away from legacy software systems and keep delivering new functionality. You will walk away with the knowledge of where to start your disentanglement journey!

Kenny Baas-Schwegler

May 15, 2023
Tweet

More Decks by Kenny Baas-Schwegler

Other Decks in Programming

Transcript

  1. Photo by Mathew Schwartz on Unsplash Disentangling legacy software approached

    with Domain-Driven Design Kenny Baas-Schwegler @kenny_baas
  2. @kenny_baas https://wirfs-brock.com/blog/2019/03/20/growing-your-personal-design-heuristics/ Heuristic “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
  3. Photo by Evan Qu on Unsplash Design heuristic “Favour monolithic

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

    should get rid of Legacy software, not create more? @kenny_baas
  5. Photo by Manish Tulaskar on Unsplash Monolithic architecture != BAD

    Monolithic architecture != Legacy @kenny_baas
  6. @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
  7. @kenny_baas 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. Monolithic architecture
  8. @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
  9. 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 @kenny_baas
  10. @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
  11. 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 @kenny_baas
  12. @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
  13. Photo by Evan Qu on Unsplash Guiding heuristic Start communicating

    business change in contextual boundaries that form the bounded context (purpose, need, responsibility, promise, user problem) @kenny_baas
  14. 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 @kenny_baas
  15. 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 with a DDD approach, creating a disconnect with the business strategy and creating a big ball of mud. @kenny_baas
  16. 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 @kenny_baas
  17. @kenny_baas Big Ball of Mud Software system that lacks a

    perceivable architecture and the model is implicit.
  18. @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
  19. Photo by Evan Qu on Unsplash Guiding heuristic Discover and

    identify bounded context with EventStorming @kenny_baas
  20. Photo by Evan Qu on Unsplash Guiding heuristic Split according

    to natural boundaries (pivotal events) @kenny_baas
  21. Photo by Evan Qu on Unsplash Guiding heuristic Pick some

    boundaries to start with and iterate. @kenny_baas
  22. Photo by Evan Qu on Unsplash Design heuristics • Split

    according to the language. • Split according to the departments. • Split according to the users • Split according to the users their needs @kenny_baas
  23. @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/
  24. @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
  25. @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
  26. @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
  27. @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); }
  28. @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) { ……………… @kenny_baas
  29. @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.
  30. Photo by Evan Qu on Unsplash Design heuristic (repeated) “Favour

    monolithic architecture over microservices architecture” @kenny_baas
  31. 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” @kenny_baas
  32. @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
  33. 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” @kenny_baas
  34. 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 @kenny_baas
  35. 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” @kenny_baas
  36. @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
  37. 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 architectural characteristics/qualities)” @kenny_baas
  38. Photo by Evan Qu on Unsplash Guiding heuristic “You can

    use Monolith and Microservices architecture together!!” @kenny_baas
  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. Photo by Evan Qu on Unsplash Design heuristic “Implement requirements

    and information based on the responsibility of your bounded context” @kenny_baas
  41. @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
  42. 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 @kenny_baas
  43. Photo by Gabriella Clare Marino on Unsplash “Our problems are

    not legacy software systems, these can be 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” @kenny_baas