Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Every message has an interface

I am developing a framework that's very similar to AF, and when I created the scripting to create custom messages, I have it create an interface for each and every one. So instead of just getting a message concrete class, a send.vi, and a do.vi, you get those 3 things and a "Handler" interface containing the required override method called by do.vi.

avogadro5_0-1662147491046.png

So, the messages never depend on any specific actor. Other benefits include being able to tell at a glance which messages the Actors may receive by inspecting their class hierarchy. The only drawbacks I can see are it requires 3 more files than a traditional message, and it results in a crowded hierarchy window.

 

Is this a good idea? Is there something like this available for AF?

Message 1 of 9
(1,969 Views)

@avogadro5 wrote:

Is there something like this available for AF?


Isn't this essentially the recommended practice for loosely coupled AF messages? The recommendation is:

  1. Make 1 interface for a set of related messages (e.g. PowerEvents.lvclass with Shutdown.vi, Powerup.vi).
  2. Create AF messages for each VI in the interface.
  3. Inherit the interface from any Actor that can receive that set of events.

Your proposal is the same as above, but limited to only 1 message per interface. There's no reason these couldn't co-exist, and I like your improved namespacing (Shutdown:Handler). On the other hand, the AF already creates way too many boilerplate files and I wouldn't want more.

 

Kudos for the effort to roll your own, btw.

0 Kudos
Message 2 of 9
(1,958 Views)


Isn't this essentially the recommended practice for loosely coupled AF messages?



I have no idea, where is the recommended practice as of 2020 best described? The only place I've seen a similar implementation is in the "Actors and Interfaces" example which of course I only found after playing around and arriving at what's in the screenshot...

 

I agree 100% on the boilerplate file count, which I see as an unavoidable shortcoming of trying to code scalably in LabVIEW unfortunately.

 

I guess my question is, when should the sender of a message know about the class of the receiver? If the answer is never, shouldn't we always use an interface (whether it is called by multiple or single messages)? Notwithstanding the file count increase.

0 Kudos
Message 3 of 9
(1,936 Views)

@avogadro5 wrote:

Is this a good idea? Is there something like this available for AF?


Echoing what's been said, the main downside I see is the extra files it creates. Usually I find that there are several messages that make sense to be grouped together (as OneOfTheDans alluded to) so in that case, I don't see too much benefit in separating all the messages into separate interfaces.

 

CLA CLED AF Guild
0 Kudos
Message 4 of 9
(1,928 Views)

@avogadro5 wrote:


I guess my question is, when should the sender of a message know about the class of the receiver? If the answer is never, shouldn't we always use an interface (whether it is called by multiple or single messages)? Notwithstanding the file count increase.


If an actor is sending a message to its caller, I'd say "never" comes pretty close to correct. Even if there's a situation where it wouldn't really hurt, the additional cost of using an interface anyway is so minimal that you might as well do it anyway just in case the opportunity for reuse arises later.

 

If the actor were instead sending the message to a nested actor, then I find it harder to justify the "never". But then again, the cost of making an interface is so minimal that I usually do it anyway.

 

The only time I don't use interfaced messages with AF now is for messages that are sent from an actor to itself (i.e. internal messages)

CLA CLED AF Guild
Message 5 of 9
(1,924 Views)

@avogadro5 wrote:
I have no idea, where is the recommended practice as of 2020 best described? The only place I've seen a similar implementation is in the "Actors and Interfaces" example which of course I only found after playing around and arriving at what's in the screenshot...

I agree it hasn't been communicated very well. I found it one day when I was trying to update some old Abstract Messages and hit a popup telling me to use new Interfaces instead. Research led me to the forums and some videos where I was able to figure it out.

 

Like CaseyM, I usually use interfaces for messages going "to Caller". But I never use interfaces for messages going "to Nested". In all my designs, the Caller knows and is coupled to the Nested's functionality so there's no point adding another layer in there. But I can see how it might be useful, especially for a Nested to inherit from multiple interfaces.

0 Kudos
Message 6 of 9
(1,916 Views)

@OneOfTheDans wrote:

Like CaseyM, I usually use interfaces for messages going "to Caller". But I never use interfaces for messages going "to Nested". In all my designs, the Caller knows and is coupled to the Nested's functionality so there's no point adding another layer in there. But I can see how it might be useful, especially for a Nested to inherit from multiple interfaces.


Another reason it might be useful to use interfaces for nested actors is if you ever wanted to swap out the nested actor.

 

For example, if the actor talked to a hardware resource, you could swap it out for a simulated actor. (I know, I know - you could/should do this at the driver level, but I think the example still works.) Another example might be if you were only interested in testing the calling actor's functionality, you could swap out the nested actor more easily if you were using interfaces.

CLA CLED AF Guild
0 Kudos
Message 7 of 9
(1,871 Views)

I too subscribe to the combination of programming to an interface, interface inheritance, and interface segregation for the reasons OneOfTheDans stated. Although, for the bulk of my medium sized applications, I replace inherited interfaces with abstract classes.

 


@CaseyM wrote:

For example, if the actor talked to a hardware resource, you could swap it out for a simulated actor. (I know, I know - you could/should do this at the driver level, but I think the example still works.)

The example certainly works when the term 'hardware' includes subsystems. This helps focus integration and system testing by stubbing out specific subsystems. (Visually, I see this as akin to stubbing out one or more intermediate nested actors in an actor tree in order to test other parts of the tree.)

 

0 Kudos
Message 8 of 9
(1,818 Views)

Sounds like there's no major cost to always using an interface to decouple message from actor beyond the additional files to load/maintain. So it's probably fair to say it's a best practice, and therefore worth continuing to use in my API's templates.

 

Keeping the interfaces "atomic" or 1 per message is really just easier for me, I don't have to think about how to break out the different methods among interfaces and I don't have to train my users on why the interface is needed or convince them to use them, they just get one for free whenever they create a message and they have to go out of their way to create coupling rather than it being the default.

0 Kudos
Message 9 of 9
(1,707 Views)