7

We have a web api c# project that was build using database-first several years ago. Now there is a need to make a transition to DDD architecture for this same project. The main reason for this is to put emphasis on business logic (that did not change a lot) and application design so it has a room to expand with new functionalities. Obviously with spaghetti code this is not so easy to do.

Since we know DDD is not just a code-first approach, but it uses a lot of different patterns and designs with domain model as it prime focus, we are looking for some answers that would make this transition as smooth as possible

  • Can we build domain on top of existing db model? (since DDD should be persistence ignorant, this should be achievable)
  • Can we build aggregates from existing db objects?
  • Would a new project from scratch (including db) be better option?

We found related article https://www.infoq.com/news/2013/02/ddd-bounded-context-large-domain but it doesn't mention building domain on top of existing context

migrated from stackoverflow.com Jan 26 '17 at 15:49

This question came from our site for professional and enthusiast programmers.

  • Should the title say "database-first"? – Ben Aaronson Jan 26 '17 at 15:59
  • 1
    Yep, corrected it – John Jan 26 '17 at 16:07
4

We did something very similar a few years ago - taking a legacy db model and trying to replace it by a new, better structured one, where all new code uses only the new model, whilst the old system is still in use. To transfer this to your case, think about a new data model designed by a DDD approach.

From this experience I suggest to build the new model mostly independent from the old one, using the persistence mechanism of your choice, and create a repeatable, on-the-fly migration process to transfer the existing "life" data into the new structure. Maybe you will also need a reverse migration process (but things are much easier if you can organize your data flow in an unidirectional manner).

So what you can do here is not to build the domain "on top" of the existing db, but "side-by-side". This will allow you to use the old database and code which relies on it over a longer period in conjunction with the new structure, which is what you typically need for a smooth transition. Then you can grow the new structures incrementally, build new code on top of it, and replace the older parts of the system step by step.

The drawback is your migration processes can become complex over time, and if you do not follow a rigid replacement strategy, you might end up with a complex system where you have to maintain one half working on the legacy structures, the other half on the new structures, plus the migration processes itself. In our case, we only replaced some of the worst structures of the old db and kept everything which had acceptable quality. Since there is a clear separation of a "backend" working on the new structures, and a "frontend" which works on the old structures, this was perfectly ok for us. But YMMV - you have to determine by yourself what works for your kind of system.

  • 1
    I'm trying to wrap up a project of the exact same nature. In our case, we approached the design from scratch. We knew our database model was poorly designed (as almost anything is which has evolved over two decades), so we started with basic "facts" and built a domain from that. We have a bidirectional data migration process, but it's primarily from old to new (we have too many legacy systems to update, so we push some data from new to old). As systems get replaced, we'll have less reliance on the database-first solution. Blank slate is the best way to go. – mgw854 Jan 31 '17 at 0:59
  • @Doc Brown That is actually what we are doing at this moment, after couple of painful experiences when we tried to redesign DB-first system into a DDD from scratch, we decided to change the way we think. It is not perfect since DDD likes clean slate, but it is more reliable and faster then starting from scratch. – John Jan 31 '17 at 8:54
  • @mgw854 blank slate is theoretically best way to go, but what you dont see is that you are replacing complex legacy system (that was working properly for years) with a new complex system that is usually not being tested enough. By doing so you will end up in a world of pain after you deploy it. The way you propose is not agile, this is not reliable transition. Imagine if you were a startup. Would you build app for 2 years and that release first MVP, or would you release first MVP after 2 months and build on top of it? – John Jan 31 '17 at 8:54
  • 1
    @John: I am not sure if you and mgw854 (and me) understand the same when talking about "design from scratch". My suggestion will allow you to redesign most of your existing db model, but of course you will need to add enough meta data fields from the old db model to make the migration work smoothly. – Doc Brown Jan 31 '17 at 10:12
  • ... moreover, I guess you want most pieces of data from the old db also somewhere in your new model. You can either see this as a disadvantage since you cannot get rid of all legacy fields, or you can see it as an advantage since it gives you a test for not missing an important requirement from the old system. – Doc Brown Jan 31 '17 at 10:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.