0

We have some entities in our code:

-"View" and View has some attributes and also contains one or many "SubViews"

-And each "SubView" has some attributes and contains one or more "Tweet" entities.

So far so good. User edits Views/SubViews/Tweet (adding/removing tweets from subviews, adding/removing subviews fro views etc) in our UI and as everything is linked it updates fine. At the moment the user after editing, can decide to make her changes "Live" Or just discard them, there is no option to save and come later.

So now we want to introduce a "Draft" system. So user can edit a View/SubView/Tweet in a draft state (This is to be persisted) and eventually decide to make it "Live". On making it "Live" the draft doesn't die. User can continue to work on the draft and make it live again. So they both live side-by-side and have to be linked.

I'm not sure how to go about introducing this is code as the "Live" is just implicit in code/db atm. Some options I could think:

  1. Add a flag to each class with Live/Draft state indication. This will mean that I need to keep them in synch between the entities that are linked together
  2. Add another "Manager" like class that holds the objects related to Draft/Live versions of the views and manages the relationship between them. Using only the current types. The Manager is the only one that knows what is draft and what is live object
  3. Add a completely new type "DraftView"->"DraftSubView"->"DraftTweet" and manage the relationship between Draft and Live entities

At the DB level I'm thinking of just adding another column to the table to say Live/Draft.

More likely, there is a better way to do this and there are patterns to help with this, so i'm hoping I can get some opinions on my suggestions or better ways to do this. Hopefully I could make the question clear.

Thanks,

1 Answer 1

2

Analysis of your options:

  • Option 1 is feasible if there is an original somewhere, so that when you discard the graph, you can reload the original state.

  • Option 2 might lead to a missing separation of concerns, with the manager cumulating responsibilities, and having to know more than it should.

  • Option 3 is interesting but might on one side duplicate some behaviors, on the other side might night additional copying when the state changes.

Since it is really about states of object, you could consider to use the state pattern:

  • It shares some ideas with your option 3, but instead of a while different object, you just need to take care about the state relevant information.
  • in the state transition logic, you need to be able to save and reload states. This could best be done using the memento pattern.

Another more ambitious thought that I will not develop here, would be to generalize the state that tou see as draft/live, and go for a version logic in which every object would be versioned, and change the problem into finding the objects related to an active version.

5
  • Thanks a lot for your comments. After reading on memento and state pattern, they do look very relevant. So I imagine that I implement Live and Drafts as states and my entities change state based on user actions. The state objects carry the corresponding behaviour and memento can help me to revert back to original state. I think this sounds quite good design now i need to see how it will fit in my current system :)
    – user642770
    May 20, 2020 at 7:23
  • My one concern being that each of View/SubView has a state and there is some relationship when one of them transitions then the other needs to transition as well in some cases.
    – user642770
    May 20, 2020 at 7:25
  • 1
    @user642770 Exactly! And indeed, depending on how the your objects are related, it can be touchy, because you may have a global state emerging from the state of the individual objects (e.g if views/subviews and tweets are interrelated but independent). One approach could be to see the relation between the objects as having a state as well (e.g. relation btw view and subview could have property active/deleted, and the relation itself would have a state live/draft; the only special case is if you switch live a relation with property deleted, you should remove the relation for good).
    – Christophe
    May 20, 2020 at 13:29
  • Hi @Christophe, Would you be able to elaborate on the versioning approach you alluded to at the end of your answer please? Or point me to some material on it? Thanks!
    – user642770
    Jun 5, 2020 at 5:31
  • 1
    @user642770 It’s very complex and would require several pages to develop so out of scope here. But the idea is to replace the binary draft/active with a sequential version number and never delete the draft. When you want to see an old version, you have to look only for the object version with the largest version number that is <= to the version you’re looking at. Here how to do it with a db: medium.com/neo4j/…. If you google for "object versioning graph" you’ll find some lore litterature and also research articles.
    – Christophe
    Jun 5, 2020 at 7:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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