LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

My way of hiding implementation of an API

This implementation (saved in LV 2011) is my counteroffer to Steve Watts. In his blog post, he discusses the importance of hiding the implementation details for the top level of an application. He makes some good points, but my contention is that he doesn't go far enough. What I have attached here is a small sample of an implementation that does a better job of hiding implementation details and does so without creating multiple layers of wrapped VIs in order to create the API.

 

Read his blog post first:

https://decibel.ni.com/content/blogs/labviewramblings/2013/04/22/encapsulating-encapsulation

and you can find my reply down the page.

 

If you're still interested in seeing what I've cooked up, take a look. I'm posting it here because there's no way to add attachments to comments in blog posts.

 

If anyone has more improvements to add to clean up these kinds of APIs, or a better counteroffer, please share!

 

PS: There is a global VI in my implementation. This is the one use of global VIs that I think is actually quite appropriate. It isn't subject to the usual problems that we attribute to globals, thanks to the fact that it only stores a 32-bit number and this magic thing called "private scope". 🙂

Message 1 of 28
(3,393 Views)

In your solution it is not obvious to me how to handle two or more instances (here power-supplies) ..

 

So one additional wire for the reference/instance/... shouldn't be hidden.

 

And about the globals: It's like the  inch scale on my Leatherman (get metric 😉 ) , I avoid to use it, but on rare occurences it nice to have it.

 

Greetings from Germany
Henrik

LV since v3.1

“ground” is a convenient fantasy

'˙˙˙˙uıɐƃɐ lɐıp puɐ °06 ǝuoɥd ɹnoʎ uɹnʇ ǝsɐǝld 'ʎɹɐuıƃɐɯı sı pǝlɐıp ǝʌɐɥ noʎ ɹǝqɯnu ǝɥʇ'


0 Kudos
Message 2 of 28
(3,347 Views)

@Henrik_Volkers wrote:

In your solution it is not obvious to me how to handle two or more instances (here power-supplies) ..


This is why you have to read Steve's post first -- the goal is to NOT support more than one instance. That would be a different architecture. The goal in this particular case is to present a minimalist API for the top layer of an application, an application that is already spec'd as having one and only one instance of the hardware. There are pros/cons to this approach, and I admit it is a style that I generally frown on. But if you accept that the goal is to present this kind of API, then we can discuss how to implement it. This is my approach to that implementation.

0 Kudos
Message 3 of 28
(3,305 Views)

Thanks for your efforts old bean, most appreciated.

The example I gave is really to describe functional encapsulation and data encapsulation.

So hiding implementation details is one prong of our attack. We're interesting in applying Coupling, Cohesion and information hiding to our designs to allow us to make flexible, robust code. The majority of our projects are pretty large scale applications, usually fairly ill-defined at the start and we do them for a fixed price. Therefore flexibility and minimal complexity are very very important to us. I think the nature of our business will also make us fairly conservative in our designs. I'm not going to apologise as it's worked for about 150 projects and I'm not starving yet!

For us hiding implementation details just helps reduce complexity. So I don't like seeing lot's of coloured wires and references on my higher level VIs. My opinion is they offer nothing to describe the problem domain. Further down the hierarchy they are fine, localised to where they are required. Functional encapsulation helps us to achieve this.

Completely concur on your use of Globals here, it doesn't cause any coupling issues beyond the scope of the lvlib.

Steve


Opportunity to learn from experienced developers / entrepeneurs (Fab,Joerg and Brian amongst them):
DSH Pragmatic Software Development Workshop


Random Ramblings Index
My Profile

Message 4 of 28
(3,277 Views)

Ok Aristos,

here is my implementation without Global

 

 

 

Certified LabVIEW Architect
Certified TestStand Architect
0 Kudos
Message 5 of 28
(3,257 Views)

@AristosQueue (NI) wrote:

PS: There is a global VI in my implementation. This is the one use of global VIs that I think is actually quite appropriate. It isn't subject to the usual problems that we attribute to globals, thanks to the fact that it only stores a 32-bit number and this magic thing called "private scope". 🙂


I used globals similar to this for the first time in a long time last year; private globals to allow a "wireless" API.  It was an error logger, so the "only one" requirement wasn't too restricting.  Instead of a DVR, I had a reference to a queue leading to a logger daemon.  It's in the LAVA Code Repository, if anyone is interested.

 

Instead of a global, one can also use a private non-reentrant VI to return the DVR (or whatever) reference.  

 

-- James

0 Kudos
Message 6 of 28
(3,244 Views)

@swatts wrote:

For us hiding implementation details just helps reduce complexity. So I don't like seeing lot's of coloured wires and references on my higher level VIs. My opinion is they offer nothing to describe the problem domain. 


Lot's of coloured wires means a lot of balls being juggled.  Perhaps too many?  Is making the balls invisible really helping the juggling?  Smiley LOL

0 Kudos
Message 7 of 28
(3,241 Views)

Attached: The Best File API Ever.

(Caution... dripping sarcasm may stain nearby block diagrams...)

Smiley Very Happy

 

Although I see the goal that Steve is driving at, I think driving all the code to a single block diagram is not viable with the current LabVIEW tools, as I hope my satirical-definitely-not-intended-for-real-use attached VI demonstrates.

 

Now, having said that, I started playing around with another approach that might get us there, which I'll post in a moment.

0 Kudos
Message 8 of 28
(3,238 Views)

Ok... that took more than "a moment"... other work took priority.

 

This attachment is saved in LV 2012. Sorry... I used features that didn't exist in 2011 and it would take too long to code without them.

 

Attached is something I created today based on Steve's comments. Essentially, I find most of the action engine "all operations on a single conpane" API unusable and unreadable. BUT I like the idea of having all the code for a given "instrument" in the same diagram. There's actually something quite nice about seeing the serialization for a by reference object -- when I have to use such -- in one location and being able to get a clean place to see the order in which functions are called, and having one place to drop probes or place asserts. It's a good idea... in theory. I just don't think LV has anywhere near the right tools for implementing it today.

 

But, since Steve asked the question, I've put together the attached library, which achieves the effect of a clean top-level wireless API with each function having its own correct connector pane and which has all the implementation code in one diagram.

 

You're probably not going to want to implement this. Some of you will... indeed, I've sketched out this idea to folks in the past, I've just never actually coded it up to show all the bits and pieces. For a few of those folks that I've sketched this idea for, they've replied, "Yes, that sounds like what I want." For most, the reply has been, "Yeah, I want something *like* that... can you please make that easier to write in LabVIEW?"

 

Anyway... unzip the attachment and open "Demo7.vi". Yeah, it's called "My Library7.lvlib"... I have a few other revisions of this with various alternate implementations.

 

You can see in this implementation the echoes of the Actor Framework. AF is what I started building after I decided that "single diagram" was a flawed idea because there just isn't a clean way in LabVIEW today to put all the different connector panes on a single virtual instrument. What I've kicked around is the possibility of giving a single VI *multiple* connector panes, and basically making the feedback node be implicit in that design. Might even be able to inherit a new one from an existing one and add additional conpanes... But that's for a future LabVIEW. An AQ-is-dreaming-of-distant-horizons sort of future.

 

As long as we're talking present day LabVIEW, I just don't think that the single block diagram is a good solution for the by-reference model. Any sane implementation requires the action engine somewhere. Even with the few nodes that Steve had in his original, the methods just aren't readable to me, and it has a conpane that is already too accident prone.

0 Kudos
Message 9 of 28
(3,212 Views)

@ohiofudu: Your solution connects the nodes with a class wire. That's exactly what Steve is trying NOT to do. 🙂

Your solution does have many good points. It is close to the solution I most favor. If I get time, I may post more on the topic.

0 Kudos
Message 10 of 28
(3,209 Views)