|
|
(3 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | = Connector and container pattern = | + | = Page has moved to [https://gitlab.eclipse.org/eclipse/papyrus/org.eclipse.papyrus-designer/-/wikis/connector-container gitlab] = |
− | | + | |
− | The connector pattern is based on the idea of Garlan and Shaw that a realization of an interaction must be
| + | |
− | a first class citizen of the application model. It must be possible that an interaction - like an
| + | |
− | application component - has multiple realizations and can be configured. The idea of connectors has been
| + | |
− | formalized in the context of UML in Robert et. al 2005
| + | |
− | | + | |
− | The interaction component is typically defined in a model library in form of a <I>template</I>. This is required,
| + | |
− | since the interaction component must be able to adapt to the context in which it is used. For instance, in case of
| + | |
− | an operation call of a component, the interaction component must provide the same operation as the component.
| + | |
− | In most cases, the formal parameter of the template is either an interface or a data-type. The implementation of
| + | |
− | the interaction component must be adapted as well, in order to correspond to the interface. The implementation body
| + | |
− | is thus provided in a form a a template of a typical model-to-text (M2T) language, in our case Acceleo.
| + | |
− | | + | |
− | The container pattern may be used to modify the way a component interacts with its environment. This pattern has been
| + | |
− | identified by existing middleware solutions, such as
| + | |
− | [http://www.omg.org/spec/CCM/ CCM] and [http://fractal.ow2.org/ Fractal]. | + | |
− | The container encapsulates an object (component) and can provide additional service and observer or manipulate the
| + | |
− | interactions with the component. In order to enhance flexibility (and readability) of the application model, it is
| + | |
− | preferable to add information about the container (in form of rules) to the model, but not the container itself.
| + | |
− | Thus, a transformation step adds the container to the model.
| + | |
− | | + | |
− | <center>
| + | |
− | [[Img:Papyrus_Qompass_container-connector.png]
| + | |
− | Connector reification and container expansion
| + | |
− | </center>
| + | |
− |
| + | |
− | The right side of the Figure above shows this principle: a component "C" is enriched with rules
| + | |
− | to apply. This information is evaluated by a transformation that creates the container and adds the elements that are
| + | |
− | associated with the rule. The component becomes an <I>executor</I>, i.e the business code behind a component. It is possible
| + | |
− | to distinguish two different types of elements within the container: the <I>interceptor</I> and the <I>extensions</I>. The
| + | |
− | interceptor is placed on a delegation connection between a port of the container and the executor. The extension is
| + | |
− | an additional element which can be connected with external ports of the container.
| + | |
− | | + | |
− | <center>
| + | |
− | [[Img:Papyrus_Qompass_statemachine-rule.png]
| + | |
− | Container rule for a state machine
| + | |
− | </center>
| + | |
− | | + | |
− | The current container libraries offer for instance the production of execution traces or the realization of mutual access.
| + | |
− | An interesting feature is the support for state-machines. Its realization requires three elements within the container:
| + | |
− | the state-machine itself, an event pool and an interceptor which feeds the pool (e.g. each time an operation is called,
| + | |
− | an associated call event is produced). These elements are captured by the rule shown in the Figure above.
| + | |
− | | + | |
− | In a similar way as the FIFO interaction component, the state machine and the interceptor are defined in a package template.
| + | |
− | The model of the state machine is defined for a component (class). The implementation of the state machines depends on the
| + | |
− | formal parameter which is instantiated with a class. The message interceptor is typed with an interface, since it primarily
| + | |
− | captures call-events.
| + | |
− | | + | |
− | The following code fragment describes the template of an operation which manages the execution of a state-machine.
| + | |
− | The code, here using the C++ language, is modeled by an UML opaque behavior. The access to the model element is embedded
| + | |
− | between <TT>[</TT> and <TT>/]</TT>, i.e. <TT>[name/]</TT> allows to access the name of a UML element. This excerpt shows
| + | |
− | the power to adapt the behavior of embedded components via the container to add new functionality that is well separated
| + | |
− | of the business code.
| + | |
− | | + | |
− | <PRE>
| + | |
− | [for (sm : StateMachine | ownedBehavior->select(oclIsKindOf(StateMachine)))]
| + | |
− | switch(m_currentState)
| + | |
− | {
| + | |
− | [for (state : State | sm.region.subvertex->select(oclIsKindOf(State)))]
| + | |
− | case [clazz.name/]_[state.name/]:
| + | |
− | ...
| + | |
− | [/for] ...
| + | |
− | </PRE>
| + | |
− | | + | |
− | The instantiation of the template with a fictive class "A" is shown in the next code fragment. This class contains a
| + | |
− | state machine with the state "state1", which appears in the code's "switch" statement. In each state, the events defined
| + | |
− | as triggers for transitions are compared with the event read from the pool (in which a timer or interceptor write).
| + | |
− | | + | |
− | <PRE>
| + | |
− | switch(m_currentState)
| + | |
− | {
| + | |
− | case A_state1:
| + | |
− | ...
| + | |
− | </PRE>
| + | |