ValueTree, Design Patterns and OO design


I am considering the use of valueTrees for a half-finished project I’m currently working on, but cannot yet decide it if it a good idea for my needs, so I thought I’d start a philosophical discussion about it to help make my mind up.

First and foremost: do any of you know of any design pattern(s) that would be the equivalent of Juce’s ValueTree implementation, alone or in combination?

That’d help me read up on it outside this forum!

Second: It seems that With valueTree, traditional GOF OO approaches are turned inside out!

Let me explain: at the moment my program is based around the traditional Gang of Four patterns of Composite for the model, with Visitors for serialization and other traversing of the model, and the Command pattern around which an undo-redo implementation is straightforward, if a bit verbose. Each element in my model is then sub-classing from the Composite pattern classes, and can additionally encapsulate all its logic, with similar classes easily sharing interfaces and behavior, as per usual.

With ValueTree though, the above (if it is clear at all the way I’ve described it), is in effect turned inside out: the complexity of the tree is at all times exposed in the program, and instead of a class encapsulating all its complexity, the complex model has to have any logic and related extra data-structures hanging off it! The discussion in this thread seems to be similar:

In a program that potentially updates hundreds of values a second, and at times uses hash-tables to store and retrieve values speedily, perhaps the above doesn’t gel well?

At the moment I am still just thinking of the pros and cons, hence the rambling nature of the second part of this post…

Hopefully I will reach some clarity in which case I will post back to this thread and share my profound OO design insights :slight_smile:

If you intend high speed access/change with ValueTree, you’re out of luck.
They are not supporting this (the basic structure is using O(N) lookup for any navigation inside the tree) [see ]

It’s correct when the tree is relatively small (current computer are very fast anyway), but when it grows, you should use your own structures.
I had to change the storage in one of my software because with > 3000 nodes cross relating each other, each time I had to search the tree, it took hundreds of milliseconds (which is not acceptable for UI related things).
BTW, the ValueTree is not a big code anyway, and the few features you might actually need will be coded in half a day.

I’d say that reasons to use ValueTrees would be:

  • if you need to undo/redo changes to the tree as a whole (this is definitely their “killer app”)
  • If you need to easily load/save it
  • If your tree may contain many different types of object
  • if you need to get callbacks when the tree changes

What I normally do is to wrap simple classes around nodes of the tree, to provide a more OO interface to particular types of object - have a look at the way the introjucer stores projects/exporters/build configs, and how the Drawable classes provide wrappers.

I’ve a friend who’s using them in a performance-intensive app, and he’s got a half-finished helper class called a ValueCache that speeds up access to often-used values. I’ll probably be adding that class to the library when it’s ready.


I’ve spent some time thinking about this and reading Juce code, and I have to say I’m still perplexed :slight_smile:

I read the Drawable code, down to the componentbuilder, which it appears I should need to make a copy of myself. Perhaps this is a good candidate for making a more abstract base class off of, that isn’t GUI component dependent, for people to use making their model-maintaining code?

What I don’t understand from the Drawable code is how it would work if I don’t just want to build the model from serialized data, but actually keep the valuetree as my main model data structure. It seems from the above that the valuetree isn’t the main model, instead it is a parallel, duplicate data structure, no?

From the Drawable example, I don’t really understand how undo-redo would work either… Is it supposed to be used with it?

I’ll get to the suggested code reading in the Introjucer now instead, perhaps that is closer to my needs…

Reading real-world production code is always more confusing towards understanding such concepts. I remember when I was first learning about design patterns a decade ago this website’s examples were extremely helpful towards my gaining an understanding:

It would certainly help having a nice caricature example of how a basic program with a serializable model and undo-redo functionality would look like using the ValueTree and associated tools! Perhaps a simple example program with a small model tree and undoable actions would be worthwhile putting into the Juce Demo app.

But of course I am well aware it is a lot of work to explain any sufficiently involved idea in a simple manner!