Hi, Ernesto,
Yes, I’m back. See some replies in-line, below.
BTW, it might be useful to discuss questions like these on the mailing list for the benefit of a wider audience.
In Papyrus-RT, when a model is created or loaded we create instances of the UML-RT implementation, e.g. ClassRT, rather than instances of the façade per se, e.g. UMLRTCapsule. I have searched throughout the codebase and façade instances seem to be created only in a handful of places for very specific tasks like
org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts.RTClassCompositeEditPart.getRedefinedView()
I was wondering two related things:
-
Is there is a particular reason for not creating façade instances whenever we create or load models?
No, but with the classic façade pattern there’s not always a particular reason to instantiate the façades before they are needed. Until some client wants its convenient features (such as they are), these objects aren’t actually needed.
What was the rationale for separating the implementation classes (like ClassRT) from the façade (like UMLRTCapsule)? I understand that the implementation classes provide customizations of UML (meta)classes specific to UML-RT, but is there any design drawback in unifying the façade and the implementation? Wouldn’t it be convenient to create façade instances right away? After all, the façade is supposed to act like a DSML. Codegen would certainly benefit from this. For example, I could directly invoke “capsule.getParts()”, on a model element, without having to either create a UMLRTCapsule instance manually or filtering the ownedMembers.
The façade is a façade because it cannot be unified with the UML metamodel implementation. It is necessary to be able to create both capsules and passive classes, for example, and the UML representation of a capsule is a class (which is the implementation of passive classes) with a stereotype applied. You can’t have it both ways, and code that knows about UML but doesn’t know about the façade still needs to be able to work with these models: it will create a class with a stereotype application, which in a unified implementation would then not be a capsule. You don’t want to lose the benefit of UML’s generality and support by so many tools, that the model can’t be manipulated in those terms. At least, I don’t. ;-)
Ok, I think I understand the rationale better. At the technical level, I see there could be another reason. The implementation classes are created by the
UMLRTUMLFactoryImpl class which specializes and “takes over” the
UMLFactoryImpl. The tool should be able to create both a passive class or a capsule and in both cases it would use the
UMLFactory, which has a
createClass method, but not something like
createCapsule, because the tool knows about UML but not necessarily about UML-RT. Is this correct?
So one of the main reasons to keep the UML-RT implementation separate from the façade, is to allow non-UML-RT tools to be able to work with the model as a “plain” UML model. But the UML-RT implementation it not pure UML. While its classes specialize UML classes, guaranteeing the same API as UML, their implementation doesn’t always yield the same behaviour as plain UML. For example, an issue that we have discussed in the past is the “getOwnedAttributes” vs “getOwnedMembers + filtering for attributes”. A client that is not aware of this distinction might expect the standard UML behaviour, but since the actual element that they are working with is an
org.eclipse.papyrusrt.umlrt.uml.internal.impl.ClassRTImpl rather than a
org.eclipse.uml2.uml.internal.impl.ClassImpl, the behaviour will be different. But since in Papyrus-RT the
UMLRTUMLFactoryImpl class
is always used instead of the default UMLFactoryImpl, there doesn’t seem to be a way to get “pure” UML. If the rationale for separating the façade was to keep support for “plain” UML in place, wouldn’t that same rationale apply here and suggest that Papyrus-RT shouldn’t be creating ClassRT instances automatically in place of plain UML Class instances?