Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving "Movie details" example diagram #2

Open
DrSensor opened this issue Jul 22, 2019 · 3 comments
Open

Improving "Movie details" example diagram #2

DrSensor opened this issue Jul 22, 2019 · 3 comments

Comments

@DrSensor
Copy link

From DrSensor/scdlang#29 (comment)

My review for this diagram (it might be a bit harsh 馃槄)
https://brucou.github.io/documentation/graphs/movie-search/TMDB-movie-query-and-detail.html

Review

Since it's not auto-generated diagram, there is 2 tips which I use as a basis:

  1. Avoid a lot of edges in single node
  2. Use pseudo-state (plus state-list when necessary). There is several tricks about this in OMG UML spec page 324-331,336

Starting from no.1
Screenshot_20190722_112729
Screenshot_20190722_115559

This can be avoided if you use pseudo state in several area. Also this happen because you use 2 edge on the same event
Screenshot_20190722_114427-2

You can rewrite it something like this

annoying_review

It also weird that there is 2 auto transition
Screenshot_20190722_115307
Just make it one edges and write it as ['/' or '/:query'] / ...


Again, make this edges one-to-many or many-to-one using pseudo-state

Screenshot_20190722_115923

Regarding to naming, don't name it to long. For example display ___ screen just name it show loading or error screen. As a side note, keep in mind to target accessibility user too.

And the state name too. The context of the child state can be inferred from the parent state. For example:
Screenshot_20190722_120813
Just name the state querying, selection, and error.


Lastly, there is a trick where you can separate the details in another block. It's a bit cumbersome for me to draw 馃槀. So, see that in OMG UML spec figure 14.12-14 page 325-326.

@brucou
Copy link
Owner

brucou commented Jul 22, 2019

Thanks for taking the time to have a good look at it. Appreciate that.

Yeah the UML specs has a bunch of stuff. That said the diagram is indeed auto-generated with yed, which is the tool I use. I mean the visualization is auto-generated (this is a hierarchic layout), the labels I put by hand. The great thing with yed is that I don't have to think about these things. I just push a button and it draws the graph. So I could for instance generate a graphml file from the Kingly machine definition, and not care about what it will look like. The hierarchic layout, the flowchart layout are generally good options, even if it is never perfect (sometimes it gives weird stuff with some edge crossing) but it is good enough.

On another note, a good tool to draw these graph by hand is bpmn.io, complying with the UML specs. It is actually a professional tool used in the industry but I found it painful to draw stuff by hand.

The two edges for the same event is to mirror the specs which gives the requirements as separated. I put that as a note on Kingly doc site. It is indeed possible to use a logical OR, but I found it better to mirror the specs. The visualization has multiple competing goals for sure, but one of them is to quickly check against design errors, i.e. discrepancies between the specs and the graph.

@brucou
Copy link
Owner

brucou commented Jul 22, 2019

What do you mean by

keep in mind to target accessibility user too

Other considerations:

  • I would not actually recommend to use to collapse edges. yed can be configured to do this automatically, but I experimented with it and found it less readable. "One edge, one line" reads and is modified faster. Maybe by hand you can make it more readable? But I'd rather avoid the work.
  • you can get an even shorter graph by observing that you could define (display loading screen, etc.) as entry action for the movie querying control state ONCE. But then again, it will be harder to modify the day that there is a transition to the movie querying control state, but in that specific case the entry action should not apply.

In short, no premature optimization till you are pretty sure that there won't be much changes in your specs. That's the most 'agile' way for me.

I agree with you on naming. Shorter is better, as long as readability is not sacrificed. On the graph instead of Movie Querying it could be Querying as you suggest. I have one constraint though with Kingly which is that all control state names must be distinct, so I usually add the context back in the name so it can be read in isolation. This is in the name of simplicity: you avoid having to prefix a control state with its parent state to avoid duplicates or disambiguate. I tried prefixing in a previous version, it is beyond annoying. xstate does have a selector system though, a bit like css, but that is something else that has to be learnt, other possibilities of making mistakes and those composed selector names are hard to type (at least properly, you can always just say it is a string but that does not help much). Maybe Rust has a better type system addressing this? The TypeScript version I used back then certainly did not do the job.

Generally speaking your comments remind me a lot of best practices for programs. I would argue that the visualization is not a program though, but the (visual) description of a data structure. I optimize that description for reads more than for writes. That said I appreciate that readability is a subjective matter, and it is great to have other people's opinions on the subject, specially the opposite ones. It leads to reconsider some assumptions as I will do now.

@brucou
Copy link
Owner

brucou commented Jul 5, 2020

@DrSensor I have been reviewing many many tools for drawing state machines, including paid tools, and I came to the conclusion that in the short term, using yed is still the best option. It is the most user friendly and productive by far, have terrific automatic layouts that are enlightening, and allow for plenty of customization of styling. Also it is free to use.

Yed may support the type of factoring that you were recommending in the discussion above. I could do this by assigning meaning to shapes (like a diamond for conditional event routing etc.). After playing with a few alternaive designs and measuring the productivity, learning cost and flexibility, I chose what seems to me to be the most agile route.

  • no meaning is associated to shape or colors.
  • node labels are meaningful:
    • A node with an Init label will be considered an initial node.
    • A node with a H or H* label will be considered an history pseudo-state
  • edges labels are meaningful
    • they carry an encoding of the transition (event [guard] / action simplest syntax)

To those general principles, I added a few conveniences:

  • syntax is loose to support any input language (yed however does not support RTL languages). So you can write labels in chinese, japanese and what not (but it will always be displayed LTR).
  • edges labels can encode multiple transitions, with each transition starting with the | (pipe) character
    • e.g. | event [guard] / action | other-event [other-guard] / other-action
  • edge labels' guards or actions follow themselves an additive syntax
    • guards and actions can be the concatenation of several guards separated by the , (comma) character.
      • e.g. guard1, guard2 means that both guard1 and guard2 must be satisfied.
      • e.g. action1, action2 means that action1 and action2 must be executed in sequence.

I rejected the following conveniences:

  • add a boolean logic to the guard label syntax, e.g. isAuthenticated && !activated
    • it seems nice to have but it multiplies the possibilities for a user to write incorrect labels. So I chose to stay with natural language. e.g. user is authenticated, feature is not activated. That is more readable and resilient to mistakes. That is at least the feedback from a few guinea pigs who submitted themselves to test the library in the real world (always looking for more guinea pigs if you fancy).

I am putting the final touches to the integration with yed, the compiler and the final API, so I may eventually reach a 1.0 and make some noise. More details will be available in the (upcoming) documentation.

Thanks for the advices and comments that you contributed, that is very much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants