Ensembles
Jeff Sutherland and Jeff McKenna
Easel Corporation, 1993
1. Preface:
In the process of object-oriented analysis and design
as well as in the process of object-oriented programming, the proliferation
of objects places considerable burden upon the analysts/designer/programmer.
This has led to the use of a number of terms - frameworks, subsystems,
model views, subjects, etc. - which are all designed to relieve the complexity
burden. Ensembles are another attempt at this problem.
2. Definitions:
An ensemble is an aggregation of components which
are gathered together as a unit and are designed to perform some limited
and related set of functions. For purposes of discussion, let us use the
following description of an ensemble and its related pieces:
Ensemble (name, components, protocol,
scenarios)
Component (roleName, object, protocol)
Object (class or ensemble)
Protocol (services, events)
Service (name, parameters, returnValue, errorConditions,
possibleEvents, messageFlow)
Event (name, parameters, cause)
Scenario (name, purpose, messageFlow)
MessageFlow (messages)
Message (receivingObject, service)
Note: The above descriptions are not class
descriptions. They are closer to definition descriptions. Let us consider
each in more detail.
2.1 Ensemble (name, components, protocol, scenarios)
An ensemble is a reusable piece within an OOAD tool.
Ensembles are designed to be reused in the white box (pattern ) sense as
well as in the black box (function) sense. Ensembles clearly distinguish
between class and instance and take a more instance based view than the
current facilities in OOAD tools.
An actual ensemble instance would have a separate
instance variable for each component. The name of each variable would be
the role name of the component.
The protocol specified here defines the available
protocol that the ensemble is committed to support. It is the external
interface of the ensemble. It is provided here for the usage of an ensemble
in another and for test generation/verification.
Scenarios within ensembles are probably more clearly
stated as use cases. They are provided here as a place to keep information
on how an ensemble is anticipated to be used. It seems that early in the
analysis/design process scenarios will be in natural language and will
gradually move to computer language as the work moves towards design.
It should be noted that when an ensemble is used
as a component within another ensemble, the only visible pieces are the
name and the protocol. The components and scenarios are only used 'internally'.
2.2 Component (roleName, object, protocol)
The roleName of a component is the name that the
ensemble will use in referring to that component. When an ensemble is instantiated,
each component will be held in an instance variable with the roleName as
its name. This will allow services defined for an ensemble to define their
activity using roleNames which will make services easier to understand.
The object in the component is the class or ensemble
which will appear in that component during execution. OOAD tools can then
insure that the protocol indicated in the component will be satisfied by
the protocol of the object.
The protocol of the component is all the protocol
required of the component in it's role. This protocol should always be
a subset of the protocol supplied by the object.
2.3 Object (class or ensemble)
We have used the generic term object to mean either
a class or an ensemble. We have not defined a class here but for ensemble
work a class will consist of a name and protocol.
2.4 Protocol (services, events)
A protocol is the external interface to the object
which is holding the protocol. As such we should be able to use protocols
as a 'type' checking mechanism.
The services of a protocol are those inputs that
the object will accept and the events are those outputs that the object
will create. Another way to say this is that the services define what can
be 'said' to the object and the events define what the object can 'say'
back.
Note that the protocol makes no statement about
what will happen when a particular event occurs. It merely states that
such an event may occur. The processing of an event is handled by the encapsulating
ensemble. Since components can be used in more than one ensemble, it is
possible for many different ensembles to handle the same events. Likewise,
certain events may occur and no action is taken.
2.5 Service (name, parameters, returnValue, errorConditions,
possibleEvents, messageFlow)
Services are the mechanism for initiating activity
in an object. Service is used here to indicate the definition of the activity.
The name, parameters, returnValue, and errorConditions
provide for full documentation of the service. possibleEvents are here
to indicate which events may be triggered as a result of using this service.
parameters and returnValue could be fully specified
as to object and/or protocol. This would result in a fully typed system.
The message flow may not belong in the service.
Some way to connect a message flow to the definition of a service. This
needs to be in the defining object. One way to do this is to have a scenario
for each service defined in an object. The message flows should not be
in the component protocols.
2.6 Event (name, parameters, cause)
Events are considered to be at the same level as
services. In the way that services are communication to an object, events
are communications from an object. Among other things, events can be used
to implement exceptions, triggers, and exceptions.
2.7 Scenario (name, messageFlow)
The scenario is a way to name and specify work to
be performed. Work is accomplished by sending messages in a controlled
way to components in the ensemble.
2.8 MessageFlow (messages)
The message flow is the procedural aspect of objects.
In its most simple form (shown here) the message flow is just a ordered
collection. Message flow should include logic as well.
Message flows can be represented by interaction
diagrams.
2.9 Message (receivingObject, service)
A message is a service applied to an object, termed
the receiver. This definition conforms to the typical usage of message
in OOP systems.
3. Discussion:
3.1 Reuse
The above definition does allow a class to be used
in more than one ensemble. In fact a class can be used more than once in
the same ensemble. This overcomes a major deficiency in most OOAD tools.
3.2 Components
The component relationship is similar to the whole/part
relationship of Coad/Yourdon. To achieve the desired flexibility, components
will need to be classifiable into two distinct types: Internal components
and external components.
Internal components are to live only during the
life of the component. Their creation and destruction are the responsibility
of the ensemble. With proper construction it will be possible to allow
the user to specify/change the class of an internal component at design
time.
External components are provided during the execution
of the ensemble and may change dynamically. Their creation and destruction
are not typically the responsibility of the ensemble. This approach allows
individual objects to be shared between ensembles. It is only in this way
that we can build co-executing applications that share resources (e.g.
a data base server).
3.3 Use of protocols
The approach taken above uses protocols to establish
the validity of design. In particular, the user is only allowed to place
an object (class or ensemble) in a component when the component protocol
is a proper subset (say isSatisfiedBy: aProtocol) of the protocol of the
object. The designer can use such protocol testing to insure that any specific
object can be used as any particular component.
As mentioned above, a full implementation of protocol
validation would essentially mean that protocol would have to be established
for all object classes. This essentially means that full type checking
is theoretically possible. Fortunately, it is possible to relax the validation
considerably and still have a useful system.
3.4 Scenarios
Scenarios are provided for these main reasons: Support
of use cases, capture of 'method' code and testing. If ensembles are well
made, scenarios should map very easily to code. Interaction diagrams should
be constructable from scenarios and could be compared against run time
generated interaction diagrams.
It appears very clear that use cases and interaction
diagrams will become more and more prevalent in OO work. They need to be
supported as mechanisms for defining ensembles..
3.5 Subclassing
The subclassing of ensembles is very possible. Subclasses
would extend and/or override components, protocol and scenarios. However,
this whole area requires some very careful thought. I would suggest some
prototyping effort first. Overriding may invalidate some scenarios and
it is not clear to me how this can be determined. I believe that subclassing
is not immediately necessary. Perhaps subclassing could be scheduled for
a later release after some good (e.g. a lot of) experience is obtained.
4. Notation
Any notation selected must support the following:
4.1 Ensemble Definition
The ensemble definition window (one window per ensemble
definition) needs to show components and whether components are internal
or external.
4.1.1 Component
A component should look a lot like a class. It should
show the name and the protocol. As scenarios are defined the protocol of
the various components in an ensemble will expand.
4.1.2 Component to object connection
A component may be attached to its object (a class
or another ensemble) using some sort of new connection (or relationship)
type. During design this can be used to verify that the component protocol
is satisfied by the object protocol. In the case where a variety of objects
might be used in the component, the designer may sequentially attach the
component to the object in question to verify that the protocol is satisfied.
In this case, an OR type of connection may be desirable.
4.1.3 External vs. Internal components
Perhaps a simple boundary around the components can
be used to indicate the internal vs. external components.
4.1.4 Protocol
The boundary suggested in 4.1.3 might also be used
to help indicate the protocol of the ensemble. Some kind of line coming
from outside the boundary to the boundary might indicate messages and the
reverse direction indicating events.
4.1.5 Scenarios
Scenarios are indicated within the boundary (except
when chatting with external components) using sequenced message connections.
Animation should easily be possible as well.
4.1.6 Event/Message hookup
The hookup of events and messages must show the event
and then the collection of messages to be executed.
4.2 Ensemble Usage
A library of ensembles should be available for the
user. These can be used within any other ensembles. The retrieval mechanism
must allow for name access and some keyword access for some number (more
than one!) classification schemes. An ensemble node should show the name,
the component names and the protocol. (This corresponds to name, attributes,
and services of a class).The user will need to be able to indicate connections
between external components and other objects in the design. This will
allow an OOAD tool to verify that the indicated object can be used in that
'role' within the ensemble. The same kind of new connection that is described
in 4.1.2 could be used here.
5. Some Random Thoughts:
5.1 Transactions
Transactions are not explicitly part of ensembles
and should not be. One could easily imagine a transaction ensemble which
would provide the fundamental objects required to support transactions.
Such an ensemble would contain data base component(s) as well as transaction
component(s). Such a ensemble might act as a wrapper to other ensembles
which actually do the atomic DB operations or it might be used as a super
ensemble for the target.
5.2 Applications
An application is merely a ensemble with no external
components, a single message for startup, say 'go', and no events. This
is a very interesting approach since it allows application development
from the top down which is currently impossible in most OOAD tools.
Acknowledgements:
In 1993, Jeff McKenna did most of the hard work synthesizing
and writing up these results based on months of research in the software technology
literature, intensive discussions within the Synchronicity Team at Easel
Corporation, with external industry experts, and numerous Smalltalk prototypes
required to validate concepts. In 2004, OOAD tool vendors have yet to implement
the concepts properly, although several key members of the Synchronicity Team
led development efforts on Rational Rose in the late 1990s. McKenna has embedded
these concepts in development of his Smalltalk software testing tools which he
began with a prototype at Easel Corporation in 1994 - see MCG
Software, Inc.