08-02-2022 05:54 AM
Hey everyone, I'm pretty new to AF and not sure if I'm using interfaces to communicate between nested and parent actors correctly.
Let's say I have three actors in my system: A, B and C (very original, I know). Actor A is the root actor that launches B and C which periodically send updates to A. Currently, to achieve that for each nested actor I've created a new "Abstraction" library that contains an interface with its methods and messages for these methods. Actors B and C use these "interface" messages to send data to actor A which implements both interfaces and updates UI as messages come in. It seems to work just fine and doesn't couple nested actor to its caller, but I guess it just feels a bit cumbersome to me to create a new library for every actor that has to send messages up the tree. Hence my question, am I doing this right, or is there some other approach I cannot think of myself?
Solved! Go to Solution.
08-02-2022 06:06 AM
Are B and C sending different updates to A? If so, yes, you're doing it right. If they're sending the same updates to A, then you only need one interface and both B and C can send to the same interface.
This assumes that you need the independence of B and C from A. There is also the strong coupling route where B and C send messages to methods defined on A directly. While there are many conditions where the interfaces are preferable, don't over-engineer the system if B and C are unlikely to need that independence. It is relatively straightforward* to refactor to create the interfaces later if you realize you want to reuse B or C separate from A.
* straightforward enough that in theory scripting tools could be created to autogenerate the interface and add it to the system, but to the best of my knowledge, no one has written such tools yet.
08-02-2022 10:07 AM
Why do you need a separate library for the interface? If Actor B sends some data to its caller Actor A, why not put the interface inside the same library as B? It's part of the API of B.
08-02-2022 10:37 AM
Taggart: depends on whether it is also used by C or not. Also depends on how aware A is of B specifically (factory pattern might obscure the relationship).
Another downside of packing it in with B is increased confusion about messages sent TO B versus those FROM B. Even if I put the interface in the same library as B, I’d still have a sublibrary to aggregate the message classes with the interface.
08-02-2022 10:49 AM
Why should B and C share an interface? Even if they send similar messages, they can each have their own interface.
If they share some hierarchy (as an example if you are using the factory pattern), then keep the interface with the parent class.
As to confusion about which messages go where - careful naming helps here. You can also use virtual folders. To steal DQMH terminology you could have a virtual folder of requests and one of broadcasts. Of course you can pick your own terminology and broadcast doesn't seem quite appropriate since it doesn't go to everyone. I like "for this Actor" and "from this Actor"
Do you find this confusing?
08-02-2022 10:51 AM
@AristosQueue wrote:
Are B and C sending different updates to A?
@AristosQueue wrote:
If they're sending the same updates to A, then you only need one interface and both B and C can send to the same interface.
08-02-2022 10:56 AM
> Why should B and C share an interface?
Because [encapsulating common behavior to give multiple entities the same language for communication] is the main reason for defining an interface? Honestly not sure how to answer you, Sam, as you seem to have some foundational assumptions that differ from mine.
Let’s be clear: B and C aren’t inheriting this hypothetical single interface. A is. You agree with that, right?
08-02-2022 10:57 AM
> B and C send different data with different types
If they send different data then you have two separate interfaces. My comments about a single interface only apply if B and C send the same thing.
08-02-2022 10:58 AM
@Taggart wrote:
Why do you need a separate library for the interface? If Actor B sends some data to its caller Actor A, why not put the interface inside the same library as B? It's part of the API of B.
If you do this, you can't ever use A in a system without B. That's OK if A and B are that tightly coupled, but then there is very little benefit in using the interface at all.
The goal of using the interface is to allow A to be used with any actor that implements the B-to-A interface. Putting the interface in the same library as B completely undermines that goal.
08-02-2022 11:00 AM
> If they share some hierarchy (as an example if you are using the factory pattern), then keep the interface with the parent class.
The only hierarchy they would share in the factory IS the interface. There wouldn’t be a parent class at all. 🙂