3

First, context: We're developing some applications using QP Framework from quantum leaps. QP is basically an event manager for state machines.

Our approach: Since we're using QP, our modules interact with events and signals (classes/structs and enums) except some very specific modules that interact by methods.

Problem: For those last modules, interfaces are easy, just a collection of all the public methods in said module, however, how about the others? Can we say an interface is a composition of other classes and enumerations?

Since the modules interact by sending/receiving events, both should know what kind of data packets (events) can travel through that interface.

Can we represent an interface like this? or should an interface only be a collection of methods? 2

edit 1: Replying to the comments below, I don't want to say the interface had nested classes, but that the interface would define said classes so they could be used as events, but from your answers, seems using signals would be a better approach. (The ADC:: prefix and the name of the interface are not the same, just some bad naming choices, as the package name was ADC and so was the interface)

edit 2: From the comments and answers below, I had no knowledge of the signal stereotype, so updating the question, I think it would become something like this?

3

This solves the classes and signals problem, however, the enum remain...

My intention was to say the interface would define this keywords, i.e. the module that implements the interface, should define this enum and their values.

Is this the correct approach?

  • From the **ADC::** prefix, I understand that these are in fact classes nested under (and owned by) this interface ADC? If that is the case, you should make that more clear by also showing the nesting of the classes in the project browser. If you want to visualize nesting on a diagram, you can use the nesting relation. (that has an end that looks like a circle with a + inside.) – Geert Bellekens Feb 10 '23 at 11:12
  • For the notation of nested classes, see https://stackoverflow.com/questions/27797531/how-to-represent-the-nested-class-of-c-in-uml/57655130#57655130 – www.admiraalit.nl Feb 13 '23 at 07:26

2 Answers2

1

The interface in your diagram is perfectly legit. UML interfaces do not have the constraints of Java interfaces: they can have operations, attributes, and all kind of associations (btw, the aggregation does formally not add any semantics to associations, and you could safely consider to remove the white diamonds), including composition (black diamond).

However it might not represent what you are looking for: interfaces express a contract. It means that the classes implementing it must provide those attributes and associations, and not that the classes will get all these features by a kind of “inheritance”.

Moreover, I’m not sure if you try to express some complex interface, or just found no better way to represent event consumption/generation. In the latter cse it would be an overcomplex and misleading approach.

For event based design, you may be interested in using signals. Signals are like classes, but there are UML elements to express the ability to process a family of events, and/or to generate events. It moreover facilitates the link between sequence diagrams and class diagrams, as a message can correspond directly to an event instance.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 1
    Thank you and yes, signals seems to be a better approach to this, I edited my question with the new approach. – Eduardo Rodrigues Feb 13 '23 at 09:16
  • @EduardoRodrigues regarding edit 2, the approach for the enums is not correct. It says that the interface is aggregated with enums. You could tell that the interface provides the enums by nesting them. But there is no way to say that the interface realization has to define the enums. Moreover, if the enums and their literals are already known to the point that you can say that the interface must define them this way... well means that they are already defined before the interface is realised. The only way to avoid this would be to make the interface a parameterised interface, with the... – Christophe Feb 13 '23 at 22:53
  • two types as parameters, and define constraints about the fact that these types must be enum and the literal names thy must define. But this sound rather cumbersome. An easier way is to add comments in the schema that explain this principle informally, without using templates. – Christophe Feb 13 '23 at 22:56
  • QPFramework works by sending signals between state machines, so they must all be unique and known by both sides of the interface. My thoughts were to say that whoever uses the interface can send those "signals" and whoever implements must be able to receive them. In this case, each signal is related to an event (UML signal), so I could comment them saying each event should declare the corresponding signal, but this is not always the case. How's the best option to say that for this interface to be implemented, these literals must be defined? Should the interface itself define them? – Eduardo Rodrigues Feb 14 '23 at 07:30
0

The model per se is legit. However, it's likely not what you intended. The shared aggregation has no defined meaning. See p. 110 of UML 2.5

shared | Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.

So unless you define the meaning of them the model has no defined meaning.

If you intend to inherit operations/attributes you would draw an open triangle arrow towards other classes. Enumerations should simply be an attribute (simple association with role).

P.S. As per Geert's comment I notice the nesting too. So you obviously over-define this by adding the (meaningless) shared aggregation. You could represent the nested classes by showing them inside the enlarged «interface». Or you use (as suggested by Geert) the nesting relation (personally I use that rarely, but it's an alternative).

qwerty_so
  • 35,448
  • 8
  • 62
  • 86