Various similar-looking questions exist but I could find none that responds to my query.The possibility of having the specified aggregation relationship while implementing an interface is an essential part of my question, which is not treated in other similar questions or their solutions.
My question concerns implementation of Design Patterns in Java. For the ease of explanation, I'm considering the Command design pattern as shown in this diagram.
Since this UML representation requires that "Invoker" should be an interface and that it should also have an N-ary aggregation relationship with the "Command" interface, it's not possible to implement it if I define Invoker as a Java interface because I can't declare non-static
non-final
attributes in a Java interface and I do need to define a non-final
Collection
of "Command" objects to establish that aggregation relationship between "Invoker" and "Command".
So, I went ahead and implemented Invoker as an abstract class, which lets me have the aggregation and also provides abstraction to the implementations of "Invoker" but I'm wondering if it is a good design practice because UML does have a stereotype <<abstract>>
but the UML class diagram for this pattern explicitly specifies using an interface rathern than an abstract class.
I've also done the same for "Subject" interface of "Observer" pattern implementation in Java for a similar reason.
Please let me know if there's a way to keep "Invoker" as an interface in Java and still achieve the aggregation relationship with the specified multiplicity. If what I did is the best way to do it, please let me know if it may have some adverse effects on the structure of a program I build using the pattern this way.
Adding below the class diagram of a short Java implementation of Command Pattern that I put up for enhanced clarity of the question. I've configured "Controller" here as the "Invoker" interface that can be implemented in different ways, e.g. "InfraredRemote Controller" in this diagram. But the Design Pattern requirement of aggregation relationship between "Invoker" and "Command" interfaces made me configure "Controller" as an abstract class because I could not find any way to achieve the required multiplicity and relationship when I configured "Controller" as an interface.
ConcreteInvoker
that implements all the things because that's not really relevant to the pattern / it's implied. Likewise, there is nothing here that shows that the concrete receiver isn't necessarily the client. – zapl