Jump to content

LabVOOP Design Patterns, v1.0


Recommended Posts

I've posted a document on my personal website on the topic of LabVOOP Design Patterns.

Here's a bit from the introduction to let you decide whether you want to dive into the whole document. :book: Feedback is welcome. Eventually I'd like to put this up on DevZone, after it has a bit of polish, but it has not been reviewed by any tech writers yet.

When talking about computer programming, a design pattern is a standard correct way to organize your code. When trying to achieve some particular result, you look to the standard design patterns first to see if a solution already exists. This sounds a lot like an algorithm. An algorithm is a specific sequence of steps to take to calculate some result from a set of data. Generally algorithms can be written once in any given programming language and then reused over and over again. Design patterns are rewritten over and over again. For example, in house cleaning, consider this algorithm for vacuuming a carpet:

Link to comment
I've posted a document on my personal website on the topic of LabVOOP Design Patterns.

Nicely done Stephen - thourough, and I especially appreciate your parallel to the gang of four patterns :) This document should definately become part of the LabVIEW documentation in the future. Now it's our job to further define the patterns that you've listed, and maybe come up with new ones where appropriate...

I also like (and agree with) the "whole new flavor of

Link to comment
I've posted a document on my personal website on the topic of LabVOOP Design Patterns.

I would greatly appreciate LabVOOP design patterns. However you Aristos mentioned in another post that LabVOOP that it's currently hard to know which is the best design since the language is so new. So I don't think that a fixed document can do the thing, LabVOOP design patterns will evolve for some time until we the community understand what is the best way to implement different things in this language. So instead of document I'd appreciate a kind of online design pattern library. Each design pattern should include

  • name of the pattern
  • verbal description of the pattern
  • UML of the class hierarchy
  • images clarifying the central parts of the code (png not jpg)
  • example code as a zip packages
  • discussion forum about the pros and cons of each design pattern in slashdot style, everybody can comment and suggest new design patterns but only the moderators can add new design patterns to keep the quality of patterns

Link to comment
I would greatly appreciate LabVOOP design patterns. However you Aristos mentioned in another post that LabVOOP that it's currently hard to know which is the best design since the language is so new. So I don't think that a fixed document can do the thing, LabVOOP design patterns will evolve for some time until we the community understand what is the best way to implement different things in this language. So instead of document I'd appreciate a kind of online design pattern library. Each design pattern should include
  • name of the pattern
  • verbal description of the pattern
  • UML of the class hierarchy
  • images clarifying the central parts of the code (png not jpg)
  • example code as a zip packages
  • discussion forum about the pros and cons of each design pattern in slashdot style, everybody can comment and suggest new design patterns but only the moderators can add new design patterns to keep the quality of patterns

The PDF is what you just asked for -- name, verbal description, image, link to example code, editorial comments. it's the best I've been able to pull together thus far. The patterns I've included are reasonably sound concept wise for LV... its the implementations that are questionable. The UML component, for example, will be hard to stabilize for some time, thus I didn't even attempt it in this draft. If you're looking for discussion about each individual pattern, I didn't think it was worth, at this point, starting a separate discussion forum for each one. You can do so if you think it's worth it.

Link to comment
The UML component, for example, will be hard to stabilize for some time, thus I didn't even attempt it in this draft.

UML is very fast to comprehend where as reading pages of text is slow and still you may miss the point. I think UML would be even more important than the text. Drawing the most important classes and their relation is not a big task. If you use something like MS Visio to draw the UML and include these drawings in a word document, you can update the drawings in a few seconds if you change the class structure of the pattern. I think UML is a must for design patterns.

Link to comment
  • 2 weeks later...
In this implementation, we seek to guarantee a single instance of Data.lvclass. We achieve this by putting Data.lvclass into an owning library, Singleton.lvlib, and making the class private. Now no VI outside the class can ever drop the class as a control, constant or indicator, so we guarantee that all operations are limited to this library.

Elegant :) This way I think I can also force the use of class constructors.

Link to comment
I finally had time to rewrite the Singleton Pattern for LabVOOP.

After some more chaotic brain activity.... this pattern works. It's however somewhat more complicated to develop than a regular class and some limitations arises from the fact that public class methods need to be outside the class. So I have a suggestion for the future releases of LabVIEW which would make this pattern simpler.

The trick is that if user could define the access scope of the class constant/control, then the user could force the class to be initiated trough the class "constructor" and the singleton pattern would be easy to implement without any external library embedding. This addition would also make it possible for the class user to force constructor calls when needed.

A user could place private controls on front panel, but the VI wouldn't run if the control wasn't connected to an external buffer source (i.e. if the VI wouldn't called as a subVI). The user could also place private constants on block diagram. These constants wouldn't initiate a buffer but would only carry type information. A wire leaving from these constants could only be conntected to new kind of node terminals called "Type specifier" terminal. All sorts of typecast and unflatten functions would have this new terminal instead of the present "required" terminals. User could also define front panel terminals to be of "Type specifier" type, but then these terminals could only be conntected to other "Type specifier" terminals.

Aristos, do you think you could implement this in a future release of LV. After all it seems to me quite powerful addition to the language :)

Edit: Some more brain work.... your design pattern would also allow users to make pure virtual classes :)

Link to comment
Aristos, do you think you could implement this in a future release of LV. After all it seems to me quite powerful addition to the language :)

Worth thinking about, certainly. At this point I don't see any pitfalls.

Edit: Some more brain work.... your design pattern would also allow users to make pure virtual classes :)

My brain is going slow this morning. How does this work?

Oh, and I did find one hole in the entire solution... uninitialized shift registers. An unscrupulous programmer can connect the terminal output of one of the exposed VIs to the inside terminal of the right-hand shift register. Then the left-hand shift register, if left unwired, would be able to produce an uninitialized (in the most terribly litteral sense!) value of the class. To really enforce the pattern, I would need to force shift-registers to be wired if they cannot access the class.

Link to comment
My brain is going slow this morning. How does this work?

I was wrong, you cannot :)

Oh, and I did find one hole in the entire solution... uninitialized shift registers. An unscrupulous programmer can connect the terminal output of one of the exposed VIs to the inside terminal of the right-hand shift register. Then the left-hand shift register, if left unwired, would be able to produce an uninitialized (in the most terribly litteral sense!) value of the class. To really enforce the pattern, I would need to force shift-registers to be wired if they cannot access the class.

I think uninitialized shift registers and all other VI properties with state cause quite a lot of trouble since they don't really fit into a pure dataflow ideology. I'd like to see a possibility to have stateless VIs which could be used to implement real recursion.

Link to comment

Well, whatever you decide doing please don't change anything in LV simply because it does not fit into a puristic idiology of some programming concept and/or have side effects that may be "misused" (whatever that is supposed to mean).

Shift registers (initialized or not) and LV2 style globals is probably the single most important reason why it is possible to do anything in LV besides passing data linearly down a wire from A to B via function Z(A). In the end it all boils down to getting real world results (on all levels).

Link to comment
I was wrong, you cannot :)

I think uninitialized shift registers and all other VI properties with state cause quite a lot of trouble since they don't really fit into a pure dataflow ideology. I'd like to see a possibility to have stateless VIs which could be used to implement real recursion.

Ah, stateless VIs. I'll add your voice to the chorus. I'd love to have that, too. ;-)

Well, whatever you decide doing please don't change anything in LV simply because it does not fit into a puristic idiology of some programming concept and/or have side effects that may be "misused" (whatever that is supposed to mean).

Don't worry. ;-) This wouldn't affect all VIs. The idea would be a VI that you could explicitly mark as a stateless VI and thus prevents uninit shift registers, local variables, the Value property of controls and requires all controls to be a) connected to the conpane AND b) marked as requiered inputs. VIs that are stateless have some very nice properties that can be used for a variety of situations. Further the code can be optimized a lot.

Link to comment
Ah, stateless VIs. I'll add your voice to the chorus. I'd love to have that, too. ;-)

Don't worry. ;-) This wouldn't affect all VIs. The idea would be a VI that you could explicitly mark as a stateless VI and thus prevents uninit shift registers, local variables, the Value property of controls and requires all controls to be a) connected to the conpane AND b) marked as requiered inputs. VIs that are stateless have some very nice properties that can be used for a variety of situations. Further the code can be optimized a lot.

Yes, I see now that optimization is one thing. Maybe inlining by the compiler ? :)

Link to comment
  • 4 months later...

VERSION 1.3 of the document is now available here:

http://jabberwocky.outriangle.org/LabVOOP_...gn_Patterns.pdf

From now on this link will work... I'll simply overwrite the existing document with any new versions, rather than having a link for each revision. That was a silly idea that just lead to a lot of dead links in various posts.

Link to comment
VERSION 1.3 of the document is now available here:

http://jabberwocky.outriangle.org/LabVOOP_...gn_Patterns.pdf

From now on this link will work... I'll simply overwrite the existing document with any new versions, rather than having a link for each revision. That was a silly idea that just lead to a lot of dead links in various posts.

Thanks! :thumbup:

p.s. Do you think it would be possible to have revision history in the document so that it would be easier to know what are the new changes in the document...

Link to comment
  • 3 weeks later...

Hi,

Assuming I understood the pattern correctly the singleton pattern makes no sense as one cannot pass the singleton object to subVIs. One is limited to using the singleton on a single block-diagram only and cannot pass it anywhere as one cannot place a class control or indicator anywhere. I think this is a severe limitation to this pattern.

p.s. This post was inspired by the discussion on private typedefs in another thread.

Link to comment

QUOTE(Tomi Maila @ Feb 16 2007, 01:32 PM)

You don't have to pass it anywhere. Just access it directly in the subVIs. The whole point is that there is but one of these so it doesn't have to be passed around. If this is not desirable for some application, then this is not the pattern for that application. There are a good number of times when absolutely guaranteeting that one and only one exists is valuable.

Link to comment

QUOTE(Aristos Queue @ Feb 16 2007, 10:59 PM)

You don't have to pass it anywhere. Just access it directly in the subVIs. The whole point is that there is but one of these so it doesn't have to be passed around. If this is not desirable for some application, then this is not the pattern for that application. There are a good number of times when absolutely guaranteeting that one and only one exists is valuable.

Yes, that's true. You can access the singleton in any place. But there are some problems when you cannot pass a wire to a subvi. Wire determines the execution order in LabVIEW. So if you cannot use the singleton wire to determine execution order, you have to carefully determine the proper execution order some other way. Well error cluster could act as such a wire but programmer must be aware that it determines the execution order.

How about changing the pattern so that this "wireless" singleton object is embedded as private data of another wired object. Then we would have a wired object but it would always refer to the same wireless object. All of the methods of the wired object would need to aquire a lease from the wireless object. The same could be achieved using a named single element queue which would be created by class methods if it doesn't exist.

Tomi

Link to comment
  • 1 month later...

What do you feel is the proper implementation of this within the scope of another project. As in, I have my own type of object, is it appropriate to replicate the entire singlton project w/ the new data type or only parts or ....

I know that it is us to utilize the design pattern however we choose, but did you have a process in mind?

Thanks

Link to comment

QUOTE(njkirchner @ Mar 30 2007, 04:13 PM)

What do you feel is the proper implementation of this within the scope of another project. As in, I have my own type of object, is it appropriate to replicate the entire singlton project w/ the new data type or only parts or ....

I know that it is us to utilize the design pattern however we choose, but did you have a process in mind?

No process in mind yet. I think at some point we'll have a template class or a wizard that scripts stuff based on the class you give it, but for now, I'm just trying to identify patterns that I see -- things people keep trying to do, and picking out the best implementation I can find for doing that thing.

These are starting points for your architecture, meant to help with "blank diagram syndrome" -- only in this case it is "blank project tree syndrome". "I need to build XYZ, ah, ok, this looks like it does what I need to get done, let me build something like that..."

I think the way to use it today is this: if you write something that is sufficiently similar to the pattern as described, then do something in the iconography or naming to indicate that this is an instance of that pattern. That way people can more easily figure out why certain bits are written in a particular way ("why did he create this shell library?" for example for the singleton pattern). And if you find a better implementation, let me know and we'll update the document as necessary (or update LV, if that's what's necessary :ninja: ).

Link to comment
  • 1 year later...

QUOTE (SPM @ Apr 23 2008, 09:18 AM)

Has anyone done the Bridge pattern yet? Would be extremely useful for a problem I have in test system configuration at startup.
No progress on the patterns document since August. I typically have time to update these sorts of side projects in the space roughly two months before a LabVIEW release (because LV is done about that far in advance to allow toolkits and manufacturing time before the release). August was when LV released last, and when it actually releases, my attention has to turn back to the next rev. I suppose this means if you see me update this document, you can bet a LV release is coming up. Perhaps I'll have to delay posting new drafts to avoid "early announcing"... :-)

As for Bridge pattern in particular: This is a pattern that you can pretty much use as is from the Gang of Four book directly in LabVIEW. There's no special behavior or alternate implementation required. It is extremely similar to the Delegation pattern which is covered in the LabVIEW design patterns document.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.