DEV Community

Cover image for It's wrong to treat "Draft" mode as a state on the way to "Final"

It's wrong to treat "Draft" mode as a state on the way to "Final"

Hagai Luger on December 08, 2018

When we build a system that needs to have a draft mode (for example an order we would like to complete later), It might be tempting to save the d...
Collapse
 
dmfay profile image
Dian Fay

You're not reinventing the wheel, you have a road with a weird surface and you're trying to figure out what rolls on it. There isn't a "one size fits all" solution: your case where a complete entity record is constrained in ways that incomplete records are not is common but not universal. In other systems, there might be well-known default values; or the entity's life cycle could simply hinge on how the values in a few always-defined fields mutate.

Separating storage is only one way to tackle your particular problem. You could, for example, break down your entity into a core with identical constraints at every stage of its life cycle, add subsidiary data to dependent ("specialization") tables as they come in, and use check constraints and triggers to enforce integrity. It's probably not worth the effort unless you have to do some pretty complicated stuff at multiple points in that life cycle, but it's an option -- and sometimes you do have the need for it!

Collapse
 
hagailuger profile image
Hagai Luger

Thanks for the detailed response!
I'll look at the option you proposed here.

Collapse
 
dmfay profile image
Dian Fay

Don't look too hard -- it probably isn't worth the effort if you only have a couple of states and don't want to do too much assembly of completed entities! I was just using it as an example to show that there are multiple ways to approach the problem, and choosing the best one is extremely situational.

Collapse
 
antonfrattaroli profile image
Anton Frattaroli • Edited

What if you had multiple final versions of the same document? Or multiple draft versions? Venturing into the territory of source control systems.

Each auto-save is a commit, each hard-save and publish action acting like a commit+squash.

Idk, just thinking out loud.

Collapse
 
binarypatrick profile image
BinaryPatrick

As someone who just created a mass messaging app, I wish I had separated them in the architecture. It was my first attempt at this kind of app. Definitely lessons learned.

Collapse
 
hagailuger profile image
Hagai Luger

Thanks!
Can you elaborate more on what you did at the end?

Collapse
 
binarypatrick profile image
BinaryPatrick

In it's current state, they both sit in the same table, along with templates too. Only an enum differentiates them. The product still has time to change but it's so late in the project it may remain that way forever.

Ultimately I don't think having them all in one table is so bad it needs to be changed, but if I went back in time I probably would split finalized from all others.

As the project was filled in, I found myself writing more and more exception logic for final. That's a code smell for sure. Because it's not split in the data layer, it has to be done in business logic.

Consider though that doing anything has considerations. And perhaps if it was separated, there would be other issues. The code would certainly have repetition. Storing them all in one table is very DRY, if nothing else.

Collapse
 
swizzard profile image
sam

depending on specifics, you might want to consider composition/table inheritance.

Collapse
 
justinctlam profile image
Justin Lam

You should read the Pragmatic Programmer.

stackoverflow.com/questions/404733...

Collapse
 
hagailuger profile image
Hagai Luger

Thanks
Can you please explain?
It seems like the link talks about development phases while I'm talking about an "object" that one of his "states" is draft

Collapse
 
justinctlam profile image
Justin Lam

Ah! Sorry, I misread what you meant then. Apologies.