Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple inheritance/interfaces with Actors

(This isn't technically specific to Actors, but my example uses Actors so I'm posting here.)

 

I'm wondering what the best philosophy is for very generic functionality, and how those could be implemented via composition or interfaces, rather than an abstract class. Some examples are:

 

  • MGI Panel Manager: Very helpful for GUI's. It lets you send "Show Panel", "Hide Panel", "Tile windows", etc. messages without needing the Actor itself to implement any features.
  • MGI Monitored Actor: Wraps up your Actor and gives debugging tools like runtime toggleable message logging, etc.
  • Zyah Message Forwarding Actor: Helps with distributing broadcast messages.

The issue here is that each of those require your Actor to inherit from classes, not interfaces, because AFAIK they each need private data.*

 

Ideally this would be something you could elect your Actor to do. Being able to have its window hidden or shown has nothing to do with any of your business logic. Neither does Monitoring nor (blindly) forwarding messages.

 

What would a better way be to implement tools that are sort of "bolt on", assuming each one requires private data? You could use the Decorator pattern, but that's not as easy as picking a list of Interfaces, and it's WAY harder to see what all a given Actor implements...

 

...which leads me to the point, that in all of these cases, your Actors don't actually implement this functionality. It's just an "ability" that gets added on, and kiiiinda feels like it's violating the Single Responsibility Principle. It kind of feels like Composition might be the best pattern here, but I digress.

 

 

*I'm not 100% sure on the Zyah one, it may be an Interface now.

0 Kudos
Message 1 of 5
(871 Views)

I would love for the Zyah Forwarding stuff to be an interface or use composition, but the underlying mechanism uses an override of "Receive Message" and I wasn't clever enough to think of a way around that. If anyone can think of a way to do it (that's just as performant or better) I'd love to discuss it.

CLA CLED AF Guild
0 Kudos
Message 2 of 5
(857 Views)

I think the general way to do some of this might be to refactor the AF itself into a composition-friendly architecture. For example, if each Actor had a MessageReceiver.lvclass that would implement the Receive Message functionality.

 

I still don't know of a way to stack multiple ones of those though- for example, if you wanted to override Receive Message once for a forwarding tool and again for a logging tool.

0 Kudos
Message 3 of 5
(849 Views)

@BertMcMahan wrote:

 

What would a better way be to implement tools that are sort of "bolt on", assuming each one requires private data? You could use the Decorator pattern, but that's not as easy as picking a list of Interfaces, and it's WAY harder to see what all a given Actor implements...

Back in 2018 and 2019 there was a push from the LabVIEW Community (mostly CLAs and LV Champions) for NI to add support for some kind of 'interfaces' to LabVIEW. I was vouching specifically for Scala-like Traits ('interfaces' allowing private data), leading to a NI Week 2019 presentation "Traits - A New Approach to Designing Reusable Code ". But for a couple of reasons LabVIEW R&D decided to take the Java Interface path (no state data).

 

However, I had a critically important use case (adding Unit Test support to abstract class hierarchy) that required private data - and after G Interfaces were rolled out in LabVIEW 2020 I came up with a Stateful Trait Design Pattern presented at the 2020 GLA Summit (7x7 When and How to [Better] Use G Interfaces). It would be easier to understand by clicking through the PowerPoint slides and following Presenter Notes, but here is the most important slide (#6) and notes:

Dmitry_0-1783795282877.png

Notes:

1.Let’s take another shot at this problem

2.Class B has an instance of reusable Class_A in its private data (composition)

3.Class B methods can directly call Class A public methods

4.Class A can have as many private data members as it needs and can directly access them in method code

5.We were all doing it this way for many years before G Interfaces came into being in 2020

6.However, composition does not provide a Host Class with Subtype of its Member Class. That’s why Class A public methods cannot be called on Class B object wire and Class B objects cannot be passed to VIs expecting an instance of Class A

7.G Interfaces changed that!

8.(Next) Let’s create a Façade Interface for Class A. Its purpose is to provide Class B (the Host Class) with subtype of Class A (its Member Class):

a.Interface A has two Dynamic Dispatch Must Override accessor methods to Class A object in Class B private data: Get_A and Set_A.

b.(Next) Add all Dynamic Dispatch public methods of Class A to Interface A with each implementation making a call to corresponding Class A method using Interface A accessor methods

c.(Next) Make Class B a Child Class of Interface A

d.(Next) Implement Interface A accessor methods in Class B

9.(Next) You can now call Class A public methods on Class B object wire or pass a Class B object to VIs expecting Interface A object …

10.(Next) Welcome to The Stateful G Trait Design Pattern 😊

11.(Next) This brings us to updated Guidelines:

  • Make it a Class if it requires Private Data
  • Give it a Facade Interface if it needs to be reused by unrelated Class Hierarchies

12.You can now easily convert existing G Classes to Stateful G Traits

13.Using Stateful Trait Design Pattern prevents Fragility and Rigidity issues of Stateful Interface Design Pattern

 

 

 

 

Message 4 of 5
(697 Views)

@BertMcMahan wrote:

 

...which leads me to the point, that in all of these cases, your Actors don't actually implement this functionality. It's just an "ability" that gets added on, and kiiiinda feels like it's violating the Single Responsibility Principle. It kind of feels like Composition might be the best pattern here, but I digress.

I do not see a SRP violation unless the 'bolt on' implementation somehow leaks into your Actor's code ...

 

Message 5 of 5
(694 Views)