On events

March 12, 2008

With the emerging adoption of event-driven architecture, arguably more important to the improvement of the corporate software infrastructure than service-oriented architecture, I thought we might take a fresh look at events per se. After a review, I’ll make an argument for extending the standard taxonomy of events to include a new event type , ‘observe,’ and an argument for extending the standard event model to include the volitional entity who caused the state change. My working understanding of events comes primarily from studying the work of James J. Odell. Mr. Odell published a couple of articles on events in the Journal of Object-Oriented Programming back in the mid-90s. They were collected, along with a number of his other articles, into a book called ‘Advanced Object-Oriented Analysis and Design Using UML’ in the late 90s, and also eventually turned into a chapters in the books Odell did with James Martin on OOAD.

The state of an object is the current value of all its attributes, including its relationships to other objects.

Odell defines an event as ‘a noteworthy change in state [of an object].’ I don’t agree, but we end up in the same place. I define an event as ‘a change in the state of an object.’ I believe the ‘noteworthy’ filter applies to a set of events, Odell that it applies to a set of state changes. I think the ‘noteworthy’ filter is a practical one, not a logical one. But we end up with a set of noteworthy state changes called events.

Odell holds that there are only two fundamental types of events (‘type’ is used here in a common sense sort of way – we will bring more meta-model rigor later): ‘add’ and ‘remove’. Add brings something new into existence – a new attribute, a new value of an attribute, a new relationship. Remove destroys something – an existing attribute, the previous value of an attribute.

Odell suggests that these definitions are not ‘user-friendly’ – that it is useful both to name event types distinctly according to their use, and to combine events that happen in sequence into single event types. While I largely agree with the former, I don’t think the latter is a function of convenience, but one that can be addressed in our model.

In Odell’s naming events according to their use he is drawing a distinction between an entity’s attributes and its relationships, and giving events related to each different names: ‘classification’ for attributes, ‘connection’ for relationships. Underlying this is the more fundamental notion that entities have identity, that is, that in instance of an entity has an identity, but that an instance of an attribute does not. The color blue has no discrete identity – we do not track it through time in its actions and relationships. More about identity in another rumination. For now, it is enough to know that there is a useful distinction between an entity’s attributes and its relationships, and that Odell’s naming convention maps to that distinction.

With respect to combining Odell’s fundamental events into compound events, I think it is most useful to simply refine our definition of event to ‘an instantaneous change in the state of an object.’ This is the logical form. The implementation reality is that there may be some time involved. This is like the distinction between functions and procedures. Functions are timeless, procedures take time.

(On a complete tangent, I wonder about how we define events for continuous processes – those which we would have to capture with differentials. Is it the same?)

Odell ends up with this base taxonomy:

  • Create: bring an object into existence
  • Terminate: sends an object into non-existence
  • Classify: an existing object is added to a new set – it gets a new attribute
  • Declassify: an existing object is removed from a set – it loses an attribute
  • Connect: add a new relationship between two (or more – my addition) objects
  • Disconnect: remove a relationship between two (or more) objects

Odells goes on to list ‘popular’ compound events he belives are useful:

  • Reclassification: to replace one classification with another
  • Reconnection: to replace one relationship with another

And three others he is less sure of:

  • Coalesce: combining two (or more – my change) objects into a single object
  • Decoalesce: splitting an object into two (or more) objects
  • Compound termination: termination of an object and all its ‘component’ objects

Odell points out that reclassification and reconnection are useful in cases where the object is not in a valid overall state ‘in between’. This brings another idea into our fundamental definition. A ‘prestate’ is the necessary state an object must be in for a given event to occur. A ‘poststate’ is the necessary state an object must be in after a given event occurs.

The entire set of valid transitions for an entity – the full connected prestates->poststates map – is its lifecycle or finite state machine.

So we again refine our definition of event: ”a instantaneous change in the state of an object from a valid prestate to a valid poststate.’
With our extended definition, it is clear that reclassify, reconnect, coalesce, and decoalesce are first-tier events. (Implementing coalesce and decoalesce is a formidable implementation design challenge.)

Compound termination is not so clear. The example Odell gives for compound termination is that of a sailboat: if we destroy a sailboat, the hull and the motor are also destroyed.

If compound termination exists as an event, I think it may be only for those strong aggregation relationships we call ‘composition.’

And my sense of composition is that it somehow works the other direction – akin to the distinction between centripital and centrifugal force. In the sailboat example, the sailboat and hull are in a composition relationship (I think Odell actually uses this example elsewhere in ‘Advanced OOP with UML), but the sailboat and motor are not. If the hull is destroyed, the sailboat ceases to exist – new hull, new boat. But if the motor is destroyed, we just get a new motor. But going the other way it is less clear. Obviously if we atomize it (plasmacize it?) with a phaser, they are all destroyed. But that seems more of a simultaneous terminate event happening, not one that somehow logically (and instantly) cascades (‘instantly cascades’ sounds wrong, doesn’t it?) But if the sailboat is destroyed in the sense of being separated into its constituent parts, hull, motor, sails, and we rebuild the boat around the same hull, is it the same boat? This goes back to our question about identity and the continuity of identity. We’ll explore this in more detail in that coming rumination. We may find some clarity later here when we talk about agency. In the meantime, we’ll leave compound termination off of our list of fundamental events. (In the real world, when a boat is stripped down and rebuilt it is generally rechistened. I spent a couple of days on the Edna, a 90′ schooner that was in port in Portimao, Portugal. It was originally a sailboat. But it had been de-masted, motorized, rechistened, and employed as a cargo carrier in the North Sea. The new owners took the boat to Porto, Portugal, where craftsman skilled in work on large sailing ships re-masted it and converted it back into a sailing vessel. And they rechistened it. But I digress :) )

Though in common use we call both an event and an event occurrence ‘event,’ we need to make a more clear distinction here. What we have been calling ‘events’ are really a supertype of events. We’ll borrow from UML (for now) and call those ‘Event Stereotypes.’ An event is a type which itself is the instance of an event stereotype. An event is associated with a particular class or set of classes, not an object. An ‘event occurrence’ is an instance of that event type that is associated with a particular instance or set of instances of a class or set of classes, i.e. an object or set of objects.

So our working definition of event occurrence is this: ”an instance of an event at a particular time for an object.”

We can capture the complete history of an object, from creation to termination, by recording information about all of its event occurrences: object(s) (which are of particular types), event (which is a reference to the ‘event’ type, whose definition includes the prestates and poststates of the objects involved in the event), and time.What is missing from this list, of course, is agency. The state change is the effect – what is the cause? Event occurrences frequently do not occur spontaneously. While there may be some that do – think chrysallis to butterfly – most do not. Our event history, to be complete, should capture the agent of change. We can call these agents ‘volitional entities’ – that will be the subject of another rumination. For now, we simply recogize that our event history needs to capture the causal agent involved to be complete. If the event is the effect, we must have the cause, otherwise our history is incomplete, disconnected, and of little ultimate utility.

Our event history gets unity by being viewed from the perspective of the object’s classes finite state machine – each object life history is the path it traverses through that FSM.

The other thing missing besides agency we can get at by examing the well-known acroynm for an object lifecycle ‘CRUD.’ CRUD may be defined as CReate, Update, Destroy. But it is more frequently used to mean Create, Read, Update, Destroy. There is a practical distinction between read only access to an entity, and access which writes to it.

But if we look at our taxonomy of events, there is a gap. We have no event whose occurrences will allow us to see the history of reads. In practice, this is a very useful thing to know.

So I suggest we add ‘Observed’ as a first class event. There is no prestate and poststate with respect to the object alone, but with respect to a given observer or class of observers, there is. If an agent has observed an entity they have knowledge of it.

I will try to expand this idea with real world examples as they come up.

We are left with our definitions and our taxonomy, with a massive debt to James J Odell:

Event stereotype: one of (create, terminate, classify, reclassify, declassify, connect, reconnect, disconnect, observe, coalesce, decoalese) each of which describes possible instantaneous changes of state for one or more objects.

Event: a type which is an instance of an event stereotype associated with a particular class or set of classes and which describes the valid prestates and poststates for the event.

Event occurence: an instance of an event at a particular time caused by a particular agent, which may be the object itself.

Event history: the complete set of event occurrences for a given object.

I will augment this with some pictures at some point – the explanation would benefit greatly from them.

But I think we have established some useful clarity around events. This clarity will be necessary as events inevitably emerge as a fundamental feature of the enterprise computing environment.

Leave a Reply