Community Coding : Design Patterns

hei all,

I started reading this book (Head First Design Patterns, O’Reilly) that gives an introduction to design patterns and thought it would be a nice exercise to try to implement those in VL. Then, @sebl suggested it could be a cool communitythingy on the forums, so let’s do it :)

I’ve set-up a repo so anyone can contribute and see what’s going on. The idea would be to produce a series of documented patches that could serve as a learning resource for anyone interested in the topic.

Also, you can check out Christopher Okhravi’s YouTube channel where he (brilliantly) explains in details the patterns of the book.

Any comments/suggestions welcome!

cheeerz

seb

16 Likes

first pattern is very simple in vl, i can try to patch something if no one is working on it already.

working on it but i’d be curious to see how you handle it :)

here is a patch that implements some ducks from the first video with the strategy pattern and draws them with skia. also made a pull request (edit: now merged): https://github.com/sebescudie/VL.HeadFirstDesignPatterns/tree/master/01_StrategyPattern

there is a Root and DuckManager patch to actually make some different ducks and manage them:
image

the output looks a bit silly tho, but i didn’t want to clutter it with too much functionality:
image

11 Likes

Thanks @tonfilm, merged !
A bit busy these days but I should be able to study it and maybe come up with something by the end of the week.

great, so next up, observer pattern! this is basically two nodes in vl, who is up for it? … hint hint:

Ok, not really sure where I’m going with this, so I’ll post here first.

I was trying to patch the thing with ToObservable nodes when I remembered something @Elias showed at LINK about Subjects. Despite the OnNext node being a bit counter intuitive at first, it seems pretty straightforward now, almost feels “too easy” to be the right thing to do :)

What would you think about that approach ?

image

VVVV.DesignPatterns.Observer.vl (49.2 KB)

2 Likes

i’ve watched the video about observer pattern and the explanations are nice, but in VL you don’t really need to know most of it, because IObservable is already the optimal implementation of the conclusion he makes at the end of the video. it’s even much more, the reactive nodes are thread safe and packed as a library to use the observer pattern as a tool in your patches.

i can only see minor improvements in your patch and hope to find some time at the weekend to make a few suggestions.

thanks tebjan, i’ll annotate a bit more an push to a branch before this weekend.

the video is pretty interesting indeed but that’s what I thought when I tried to patch it : the implementation of the pattern felt a bit overkill in VL :)

on another note, I started looking at the Decorator pattern and as he says in the video, the example from the book is not that suitable … I’d like to find something a bit more related to our interactiverealtimemultimedia stuff :) I’ll try to come up with something !

EDIT : pushed to a new branch. One thing though, when I re-opened the patch, the Draw (WeatherStation) node was pink because Object Reference not set to [...], even though the inputs from the Cache region were changing.
Also, the Has Changed output of the region was not reacting. I had to delete the Draw node for the Cache region to react again and then re-create it. Moving the Draw node inside the ForEach did the trick but I wonder if it’s the way to go here.
Why does the fact that the Draw node has nothing to operate on blocks things upstream ?

1 Like

there was an on open bug recently, was fixed yesterday. could be the issue. did you try with latest alpha?

yep, just installed alpha c848148d6a and moved Draw outside Foreach, Draw is pink again on startup.

in the first frame there is the data that is provided on the (white) create pin of HoldLatest. the patch doesn’t guarantee the order of execution so that the OnNext is definitely called before Draw.

so if you put some meaningful default on the create pin it should work. you should do that anyways, because you never know when the wheather station will send something.

on a second look, i think the WindowDisplay should be connected directly to the Draw. It’s always the same reference, regardless of whether there is any data or not. the observable just needs to update the internal data, Draw should not depend on the update via SetData.

Ok, thanks for the pointer !

Makes more sense indeed, I wouldn’t have think of that since you need to connect something to the output of ForEach for it to evaluate. It kinda makes you assume that you have to link things from the output of the region for further processing. But yeah, that makes sense now :)

I’ve updated the patch with your suggestions, thanks !

Hi,

I use pattern a lot in C# so for testing I’m trying in VL. Here is a first shot at Composite, bad naming for now and patch only. Will probably push to github later.

For the class that will implement the interface, I must add manually the properties contained in the interface right ?

CompositePattern.vl (26.9 KB)

2 Likes

All right, I think this should be the beginning of a Mediator in VL.

13_MediatorPattern.vl (38.2 KB)

I’m not sure if the Notify node can be putted inside of the ConcreteMediator node. This would need some kind of “this” maybe (another forum topic is mentioning that feature). Also it is unclear to me how to properly make use of a SetMediator in a data flow context. Will see.

Some progress but I’m stuck on how to notify the Mediator from within Component1 and Component2

I’m trying this but it’s not working :

When the Process called DoA is called then it should also call Notify from the Mediator with MessageType A. Same approach for MessageType B.

13_MediatorPattern.vl (57.1 KB)

You have a cycle here:
image

VL first reads the value on pads and only writes them at the very end. Your components read from the Mediator pad on Create - however no one intialized that pad yet, so VL will create a “default” instance and feed that. Then later on Update you actually write the “real” mediator, but that’s too late, your components already work with the “default” mediator.

So, to break the cycle you have two options:

  • Place the ConcreteMediator above your components and add them to the mediator explicitly later via an instance operation on the ConcreteMediator class
  • OR, add a SetMediator operation to your IComponent which you’ll call inside your ConcreteMediator on all the received components - that’s maybe the more elegant approach as you only need to connect the components to the mediator and “tying the knot” is done automatically.
1 Like

Here’s an updated version with the second option from above - does that answer your question?

13_MediatorPattern.vl (60.1 KB)

1 Like

Yes thanks a lot, I understand better now. Also I had this feeling of not doing something very legal while putting those two Mediator pads on top.