eXploratory Modelling Explained
This article describes an approach to modelling that is relatively unknown[i] . It capitalises on capabilities of modern programming tools and languages, especially dynamic qualities, as well as advances in object-oriented modelling.
It empowers the development of DSL’s, using what might be called a meta-DSL approach.
For the examples in this chapter (as in most of our projects) we have used a Smalltalk development environment, VisualWorks[ii] in particular, but the approach is in no way exclusive to the Smalltalk language or environment. The author has also applied the approach in a Microsoft VisualStudio environment with C# and Java/Eclipse/IntelliJ with comparable success. The approach is called eXploratory Modelling. Its aim is to significantly improve the modelling and requirements effort.
We will start by describing the overall xM process and an example xM session. This will hopefully convey the “feel” of xM. After this we will introduce several relevant theoretical issues intended as a first attempt at laying a foundation for xM practices.
A more compact introduction can be found in this article: eXploratory Modelling Introduction.
Reflektis provides training to effectively use this revolutionary technique: eXploratory Modelling (Training)
The xM process
[toc]The actual xM process consists of two parts, possibly iterative:
- Elicitation sessions with clients, domain experts or business experts
- Transformation of the resulting domain into an implementation
During the sessions, of which you will get a feel in the next subchapter containing a walkthrough of a typical xM session, domain experts actually build a running domain component. This is an executable component, executing the defined business processes, and validated as-they-build-it by the domain experts.
After this phase, or iteratively if needed, the executable domain can be transformed to run on the platform of choice, i.e. Java EE or .NET or any other platform. The implemented domain can remain in Smalltalk which will require minimal if any transformation (this is my preferred strategy), or in C# or Java or another programming language. We have experience with the following strategy that worked surprisingly well.
- Export the implemented classes to XMI. We have written a simple but usable component to do this in Smalltalk, which is available for VisualWorks in the VisualWorks public repository[iii] under the name xM-XMI Mapping.
- Import the resulting XMI into any UML tool (such as Sparx Enterprise Architect or Rational XDE)
- Export and/or transform the resulting model into a target platform such as .NET using the UML tool
The result is an implemented domain as an executable class library, not just a class stub framework as in some other modelling approaches. More on this process later.
An xM walkthrough
This subchapter will describe a typical xM session facilitated by an expert modeller who should be fluent enough in the IDE to implement the model on the fly as prompted by the workshop participants who are the domain experts. However the actual programming skills in the programming language used need not be sky-high – basic skills are usually more than sufficient.
This subchapter is written in the first person (“I did this, then that”), from the viewpoint of the facilitator.
The goal of this subchapter is to convey the “feel” of an xM session, and to communicate the prime patterns to apply. In the rest of this article some of these patterns will be elaborated upon further. Finally we will attempt to lay a more theoretical foundation.
We will take a simple example that may seem familiar to those who read the book on Domain Driven Design by Eric Evans[iv] a Cargo application (for a sample Java implementation you might check Github). During the creation of this object model the readers will hopefully appreciate the subtle differences of this model with the one from Eric Evans’ book.
We will use VisualWorks Smalltalk from Cincom[ii], but in the various Smalltalk dialects the process would be very similar.
Please visualise the following setting. I, the facilitator, behind my laptop running the development environment and projecting this on a large screen that is visible to the audience. The audience may consist of one or more domain experts. The extent of the group is determined of course by the scope of the session. Try to keep the group small to enable maximum interaction. Also don’t be afraid to do several sessions with different domain experts on the same or overlapping domain areas. This will only make the domain richer. I am never afraid of conflicting domain definitions — this is a fact that we need to support instead of discourage as we usually do when we do requirements engineering. Try to centre any discussions around the domain objects on the screen, the components from the business domain, and avoid direct discussions between team members. The domain objects should be anchors of the discussions. Sessions should be short, typically a maximum of three hours, with at least two breaks between. These sessions are intensive, or should be, and longer sessions are hard to keep up.
To start the discussion I ask the workshop participants to decide about an object that reaches a certain goal, an end goal or state of the business domain. I talk about demand-chain processes, about flexibility, and about inverting time (see the subchapter on Reverse Time Pattern for more on this introductory story, as well as the article on this pattern). The question, when this story has been told, is:
“What object can we find that, when reaching a certain state, accomplishes a relevant business goal?”
The group decides on Cargo, which is delivered to a customer site. So I start with creating an instance of Cargo. For this I will need to create this class in the browser. I usually talk my way over this, since most of the artefacts in the domain, objects, methods and variables, will be created dynamically as you will see shortly, except classes. This is a feature of the IDE that could easily be added.
In the illustration below you can see I created a package called xM-Walkthrough, with a Namespace[v] called XMExamples. With this namespace selected I ask a menu and select New Class…:
This will open the standard Class creation window. I fill in the class name we want: Cargo. I ignore the default options:
The previous steps are done quickly and covered-up by explaining I do some technical groundwork which is not relevant.
Now I am finally able to create our start object:
This will open a window you as an xM modeller, and the workshop participants will become very familiar with. Things will start coming alive now!
The inspectors are the business domain objects we will play with continuously during the xM sessions. There may be dozens of them on the screen at any moment during the sessions, and may contain links to hundreds or even thousands of other objects that are not explicitly represented on the screen in inspectors. These objects may persist during many sessions, we may even have some in the last sessions that were created in the first! This is the power of this approach, that we do not start from scratch every time, but start in a living world in which objects begin as trivially simple things but become more and more able. Nothing goes down, everything evolves, morphs, into the functionality we are aiming for.
The other window most of our time will be spent in will be the debugger. For business domain experts the debugger is usually introduced as the “object message-passing hiker”. It is a small backpack on the objects we create to trace their journey through life. They should not feel they are doing software development or programming; in fact I even don’t want to feel that way myself when I am working on the business domain!
The message passing metaphor is our “hook” into the domain behaviour, and the foundation on which new objects (with their responsibilities) are created.
The inspector “is” our object. I point to it (hand-waving is important!), and ask the session participants to see this window as our business object itself, by using a bit of imagination. Human beings have imagination to spare, so this is never a real problem in our sessions. And probably this simple cargo object we have created in the first few minutes of our domain modelling sessions will live for a long time, maybe during the entire modelling effort! It will remain, growing, evolving, morphing, being put to sleep and woken up again over the course of many sessions.
Now the time has come to do a bit of conceptual thinking. The object is there, but it cannot do anything yet, and we need to think back to why we were doing these modelling sessions again. Oh yeah, we were building the domain model for a cargo application. So if that were the case – what would be the purpose of this application? Or better: try not to think about applications at all. Think about the problem or business domain: what is the purpose of the cargo company? It will probably not take long to come to the insight that the purpose in life of the cargo company is to pick up cargo at one location, and move it without attrition to another location. Secondary purposes exist, such as doing this efficiently, at least as efficient or cost-effective as existing or potential business competitors.
When this insight has been declared viable, I take a little time to explain to the domain modellers that we need to adopt a specific way of thinking about problem domain issues. This is an explication of the Active-Passive Pattern in combination with the Time Inversion Pattern. This story however is not one I tell in the context of software development or modelling. You should avoid doing that also. Concentrate on explaining the concept to them from a business management perspective, or from the perspective of supply chain management processes. Explain that companies have adopted this pattern on a global scale in the past decade, companies like Toyota and Nike. Explain that business process theories like Lean, Six Sigma and supply chain management contain this pattern as a powerful tool to help enterprises create efficient and flexible business processes.
In the Active-Passive Pattern, objects do things themselves, and generally avoid things being done to them. In the “real” world this is the other way round, and that is exactly what we want to achieve here: turn things upside down, in order to create extendible, complex models. I call this process mirroring. The Active-Passive Pattern is nothing more than a simple trick to enable complex and scalable models.
Viewing the domain object we created with this newly gained perspective, what would be the last thing this object would need to do to fulfil the business goal? After some discussion the group might come to appreciate that the goal could be to deliver the cargo.
in our workspace and evaluate this expression with Do it. Notice what we are doing? We are proceeding “as if” our application was already finished, as if all objects already know what to do!
Of course an exception pops up:
The Cargo object exists (we are evaluating the expression self deliver in this object, in the inspector). However we are asking it to do something that it does not yet know how to do.
No worries. Click the Define it… button, and up pops the debugger, our second friendly neighbourhood tool:
The environment has done a few nifty things for us. It has dynamically created a method deliver in the class Cargo, restarted the execution of the code that we started in the workspace, and interrupted the execution thread in this new method. We can see that the method body has been filled in for us with a neat self halt, which has opened this debugger.
I usually make a little joke here that modelling this way is really efficient: we have already built our system! We have cargo, which can deliver itself.
Reality is a bit more demanding, but this way in which the model should unfold is important to explain. We are in the execution chain of business or domain objects, and we have indeed arrived at the last step in a relevant business process – there should be a clear and shared understanding of this principle.
Now the next step should be to think about the last preceding action. That is: what needed to be done, or what state should we have created, in order for the delivered state to be really done? Look at this as a sequence of steps, in effect a business process, which we are building up in reverse time. This is an application of the Reverse Time Pattern. We are in the last message sent in a relevant business process. Now we need to think about the last message before that.
What could it be? Imagine yourself to be the cargo. I repeatedly urge the workshop participants to identify themselves with the active model objects they are working with, to anthropomorphise. You are there; you have fulfilled your purpose in life. But what was the last thing that needed to be done before achieving that state of bliss?
Usually several alternatives are put forward. One could be: “go to the destination”. Or “put yourself on a ferry to the destination”.
The second option is interesting because it introduces a second object we have not yet created, but one clearly of a different type or class: a mover of things (could be a ferry, a ship, a train, etc.). Help the group appreciate the potential thinking error, in thinking about the “mover” object being active, and the cargo object being passive. In this case we might decide that cargo will have sufficient active properties in making its way to its destination, so we will delegate the final delivery responsibility to the mover:
For now we will leave the rest of the session to the imagination of the reader (or their inspiration!). We hope it is clear that by traversing the backward path, the demand-chain path, we slowly implement a complete process. And that by doing it in this fashion, this process might very well be an unexpectedly efficient and flexible process as well! We often come up with interesting alternatives of processes that were executed since the Stone Age without any change.
Many side paths may be explored, many of which may turn out to be wrong or inappropriate. This way of exploring the domain should be executed without fear: we will make mistakes, decide to throw away entire parts and build them again. The environment will help us in doing this without hampering our progress. Usually in the beginning the participants need a lot of encouragement to build up their courage to explore, try out, change, and re-think their decisions, but as they learn that the environment is actually helping them in doing this they gain courage and start becoming more and more creative.
This is always a very satisfying phase in the workshops.
An important issue concerning modelling has been tackled here as well. We mention it explicitly because it is a recurring issue. We were able to answer the question: Where to begin?
In subsequent sessions the model unfolds. Be not afraid to attempt alternative paths to the same or equivalent goals. The purpose of these sessions is not to mould a business process in concrete. The resulting object model should be seen as an enabling web of objects, a semantic web, which is able to reach the same goal even in ways not explicitly modelled or considered while modelling.
The sessions should also be productive. We do not need nor want a long stretching period of modelling sessions. The percentage spent in these sessions should be small. We need a lot of time for implementing the technical connections, typically more than 4/5 of the total implementation effort.
xM is very well suited for software teams that want to apply agile processes. The acronym xM is not accidentally similar to XP (Extreme Programming). The x in xM could be interpreted as extreme! Extreme Programming originated from software development best practices that were common in the Smalltalk community and was codified by Kent Beck in his seminal book[vi]. Many Smalltalk developers employ some sort of domain prototyping similar to xM, and like extreme programming, until Kent Beck published his book, this practice has never been codified or published. Graphical Smalltalk environments like VisualWorks, Squeak, Dolphin or VAST are best suited for xM sessions because the runtime objects and the development environment are so tightly integrated that in fact they cannot be viewed as separate. While in most development environments the deployed and implemented executable is different from the programmed stuff, this is not so in Smalltalk. Created objects, as you have seen in the walkthrough, can be modified while remaining in existence. Recompiling in Smalltalk environments is a different thing! This property of most Smalltalk environments can be utilised to the max for xM.
In Smalltalk, application development should be viewed a bit differently: an application in Smalltalk is developed within the IDE; in fact the IDE is itself a Smalltalk application. All objects in the Smalltalk environment live inside an entity called an “image”. Living dormant on disk as a file, this image is quickened, re-awakened, by the Smalltalk virtual machine. On closing a development session (or, indeed, an application execution) this set of objects is persisted on disk again. In Smalltalk, new objects and new classes are created by respectfully asking already existing Smalltalk objects to do so: morphing existing things creates new things. There is no real experience of compiling and deploying. Creating an application in Smalltalk is more about stripping out unnecessary objects to create the runtime.
The xM approach fits in with the minimalistic approach that prompted some proponents of agile methods to eschew modelling and UML. We think that xM brings you the best of two world: the advantages of having a model that can be viewed and played with, plus an executable class library that can be fitted with a complete set of unit tests[vii], albeit one that needs some transformation effort. We will talk about that shortly.
xM also delivers what MDA attempts to deliver, at least partly. The result is a repository of objects that can be viewed as a UML model, but that also lives as an executable, verifiably running set of objects. You can play with these objects. Both representations have great merit.
Modelling has always been an important part of software engineering, or engineering in general. We use models to capture the problem domain in a way that is most cost effective: the model should require much less effort, yet be “complete” enough to help in achieving a full implementation.
A model is a replica of what we actually want to describe. It is a representation of the “thing“ we want to describe; in engineering this “thing“ usually is a system we want to build. A common definition of a model contains the element of simplification: the model is a replica of the “thing“ with all “superfluous” elements removed. Of course this introduces an interesting and not so easily resolved dilemma: did we not remove elements that will turn out to be important? Who decides what is superfluous and what is not?
In this sense, models also play an important role in capturing requirements.
To build models, we use a language or several languages, depending on the context or the aspect we want to model. In software engineering a unifying effort has been successful and has resulted in the Unified Modelling Language or UML[viii]. The UML has gone through several versions, but can be challenging to use. It is often perceived as too complex, difficult to learn, and hard to translate into a concrete implementation. As a rule however, the UML captures the domain in a generic sense: in the form of a class model. Most UML models contain little or no instance models, and if they do, they are usually additional and in no way complete, nor are they intended to be complete. In this way UML models are more abstract than, say, home models or car wind tunnel models. In no way this should be regarded as a fundamental shortcoming, we are just stating characteristics.
A popular trend has become known as Domain Specific Languages (DSL’s), as an attempt to overcome the overly generic UML and create languages or vocabularies more tunes to specific business domains. These models may be somewhat easier to use, but we think they have a lot of shortcomings, especially regarding their domain-specificness: domains are seldom isolated and interact constantly, sometimes intrusively. How will your DSL deal with that?
We sometimes coin the Smalltalk environment the DSL of DSL’s. An article that talks about this is DSL for the Uninitiated – Domain-specific languages bridge the semantic gap in programming (appeared in Communication of the ACM, 2011, No. 7). The author used Ruby, but we think Smalltalk (which was an important inspiration for Ruby) is even better suited.
The common definition of models is not one we adhere to in xM. We view models as reflections of the thing we want to model. The model mirrors the real thing. The concept of mirroring creates a powerful metaphor that helps our minds in applying models effectively, and not falling in the trap of viewing the models as somehow goals in themselves, or as more real than the thing it models.
All accumulated knowledge concerning modelling complex domains, and the various patterns that can help in making decisions, are equally appropriate for xM. However three patterns or styles are especially important in xM, and are in the modelling literature in general undervalued in a way that merits special attention here. They are:
Of these pattern the first is best documented but the other two are strangely absent from most pattern literature, or if they are, they are interwoven in other patterns. For example the Time Inversion Pattern is not explicitly documented anywhere, but it certainly has become an important part of modern supply chain management business process descriptions. It just has not elsewhere been published as a pattern yet.
Domain Model Pattern
For a proper understanding of xM in the context of a complete effort that delivers a solution to a customer, the reader needs to have a clear understanding of what a domain is, and how the part of this solution that is called the domain is isolated from other parts. xM delivers an implemented, complete, fit-for-purpose domain. It does not deliver a complete solution, which will consist of several additional components, such as user interfaces, persistency solutions, or others, which we call technical components. To visualise the role of what we call a domain, in relation to these technical components, we draw the following diagram:
This diagram is also called the Sunflower model or the Satellite model. It is topologically not very different from Layered Architecture, but cognitively it conveys the important message: the business should be central in our solutions.
The diagram contains a central component: the Domain. This is the business domain containing the required business functionality. There are several attributes we want this domain component to conform to, because we can derive most value from xM if we follow these guidelines:
- The domain component contains only domain functionality. It should have minimal if any technical content: no databases, GUI, or computers.
- The domain has no dependencies on any technical components such as the ones mentioned above.
However, a business domain implemented as such will have little value. For example it has no user interface to communicate with it. Therefore connections must exist with what we call the technical components. It is not within the scope of this article to describe ways to implement this coupling, we will only mention that we use adapter technology to connect the business component(s) with the technical components in such a way that is has no or minimal impact on the requirement that the business component has no awareness of technology. Several articles on this site elaborate on this, for example Business Centred Architectures (article in Dutch).
To aid in understanding this architectural design principle or style, please visualise the domain as a replication or mirroring of the real world of the business. Concepts and processes as they exist in the business or problem domain can be found here. We do not build a domain component as an implementation of an automation solution, or business process, but we re-create the business in a mirrored format. The business process model should be viewed as a derived or implicit result of creating the domain model.
This mirrored format is especially recognisable in the two main patterns we describe below. A mirror reflects, but it turns some things around! The attempt to create models that resemble the real thing as closely as possible is a fundamental mistake, and we hope to have demonstrated a different approach here. The trick of applying the Reverse Time and Active Passive patterns will create infinitely scalable domain models. Modelling complex domains without applying these patterns will produce models that collapse under their own weight.
The technical components can then be seen as being there for only one reason: as non-functional components they synchronise the mirrored business with the real, outside world. These technical components should be understood as nothing but synchronisation mechanisms. When viewed as such, we have a cognitive aid in applying these components wisely, and not fall into the well-known trap of endowing them with too much business logic.
We will now briefly describe the two mirroring or reversing patterns. In describing these patterns we follow a pattern template. These patterns are also documented separately on this site.
The Active-Passive Pattern
A domain model will become large and very complex. This is nothing to be afraid of. It is how it should be. We want complexity! The intent of the model is to capture the domain, that is: reflect the real world. This model should be functional when very small, but be willing to grow, indeed to be infinitely scalable. However, in order to avoid a model that is unmanageable we should not make the fundamental error of trying to model the domain as close to the real world as possible. A simple trick is to turn active and passive around: active objects in the real world are modelled as passive, indeed even almost devoid of complexity in the sense of behaviour or responsibilities. Passive objects in the real world on the contrary are modelled as active, taking initiatives, doing things. The responsibilities endowed upon them are precisely those activities that, in the “real” world, are done with them. This will help in realising the intent (this is another aspect of turning-around).
Also Known As
- The World of Roger Rabbit
- Activity inversion
- Looking-glass world
A person pays a bill. He owns an account to pay bills with. The person is the active object in the real world. He pays the bill by opening or accessing the account, creating a transaction, telling the transaction the amount that he copies from the amount contained in the bill, as some other information. And finally he tells the transaction to go ahead. He is a very complex object, with many responsibilities and many relations with other objects. The objects bill, transaction, account, are passive. In fact they contain only the information (data) necessary for the person and usually contain little responsibilities. They are often trivially simple.
There are many passive, exceedingly simple objects (i.e. an Account), and few active, exceedingly complex objects (i.e. a Customer). Usually the active objects correspond to actors in the use cases, or external agents or triggers. The passive objects are data containers, with information used in a business process.
The sequence in behaviour is rather critical: first do this, and then do that. This is called process brittleness. The process is not easily changed. The few exceedingly complex active objects are strongly coupled to a lot of often trivially simple passive objects (typically more than three) with which they perform all kinds of tasks. The system can capture the business problem domain reasonably well when still small, but as the domain grows (that is, the model of the business domain in the software) it becomes increasingly difficult to manage, until expanding the domain model becomes virtually impossible because of the exploding transitive dependencies. The model collapses under its own weight. This is what is most often the cause of the exponential cost curve of computer systems we build.
The Active Passive pattern describes the world, or complex systems, by employing two rules:
- Objects that are active in the real world (machines, systems, persons, committees) are modelled as passive, that is they do not initiate actions themselves, and any responsibility they have (usually they have responsibilities) are delegated to other objects
- Objects that are passive in the real world (documents, cars, products) are modelled as active: they initiate actions, take responsibilities upon themselves to reach a business goal. They typically delegate most of the actions needed to finish a business process to other active objects, and in doing so succeed in staying simple and small.
Association hubs are, when this pattern is properly applied, greatly reduced in number. Association hubs are classes in the model with many associations (more than three is often already too many!). Inversion of activity turns activity and passivity around. In the example: the person has almost no responsibility. Instead the bill has the one main responsibility in this context, namely to “pay himself”. The bill starts the entire process of paying by contacting the person (someone has presumably created the bill, and this someone told the bill: “I want some money from this person.” The bill only needs to ask the person for one thing: an account payable. After receiving this account he proceeds by telling the account to create a transaction for himself. The bill is done now; the chain of responsibility has been transferred to the account. However, account does not hold this responsibility for long. He creates a transaction for the bill, and subsequently tells this transaction to go ahead. All the rest is done by the transaction. A simple rule of thumb is that any responsibility of an active object in the real world can be relocated to a passive object in the model.
Active objects should limit themselves in the number of responsibilities they have: typically an object should have only one responsibility. There may be more defined in the interface of the object, but these should be delegated to others. Good objects are lazy!
The distribution of complexity over the model is more balanced. Some objects are rather passive but are usually linked to several other objects. Some objects are rather active but linked to few others. This way there are less complexity hubs in the model. The resulting or generated processes are more demand-chain and more easily changed. Processes are not the source for the structural model, but rather the responsibilities of a few key objects (like “bill” in the example above). This recurs in the way the domain model structure comes into being, by employing the Reverse Time Pattern that is described in another subchapter.
The domain model may be large, but any segment of it is loosely coupled.
- The Active Object pattern[x] should not be confused with this pattern. This is a pattern that is mainly used to model objects that contain their own thread of control, to be used in concurrent systems.
- The domain-centred design principle is also strongly related to what Craig Larman calls the Expert Pattern[xi].
- This pattern is usually applied together with the Reverse Time Pattern.
- There is a strong relation between this pattern and CRC sessions. In CRC sessions, workshop participants play the role of objects in the customer domain. The facilitator usually emphasises the need to choose objects in the domain that are usually considered passive
The Time Inversion Pattern
The Time Inversion Pattern is used to model dynamic collaborative behaviour between model components. To choose which responsibilities should be endowed upon a component, the modeller considers a goal that should be reached by one or more key components. This goal should be an end-goal. There may be more than one end-goal, but one at a time is chosen for a modelling session. Reasoning backward from this end-goal the modellers searches for other components to delegate behaviour to, but in an inverted time frame: the first modelled object implements the last step in reaching the goal, the second the last step before that, and so on. The choice of candidate objects is from a list of active objects obtained from the Active-Passive Pattern.
Also Known As
A model that implements a business process that builds and delivers cars would probably contain an active object Car. The main responsibility, as last in the business process steps, could very well be: deliver yourself to the customer. Sometimes a responsibility named “sell yourself” is used.
How can a car deliver itself? Well, we define a method (=responsibility) in the class Car, called deliver. We dive into the method that should be executed when the car does this. What is the last thing that should be done in order to satisfy the deliver responsibility? We might decide that this is the fact that the car dealer drives the car to the customer site. So we need a CarDealer, and we create this class/object with the responsibility driveToCustomer. How can the car dealer drive the car to the customer site? He needs to have the car. The car, in order to be able to exist on the dealers’ site, needs to build itself: build. This is a new responsibility, in the case of aggregates largely delegated to the composing elements, etc.
The picture we want to unfold here is exactly that: of unfolding. A business process is created dynamically, can in fact be seen as generated from the collected interfaces of the web of available objects. Business processes should not be hard-coded, explicitly modelled, or contained in a separate software component, as is often the case for example in Service Oriented Architectures.
Where do you begin modelling the customers’ problem domain? This strategy makes this simpler: begin with the goals the business wants to accomplish.
How can you know that the way you model things that are done, are not modelled in such a way as to be almost impossible to change?
Modelling a complex business domain often is very hard, and it is even harder to find out where to begin.
Walking backwards along the process chain, creating active objects along the way, the car would build itself, parts would build themselves and assemble themselves, factories making the parts would pay themselves, etcetera. This is a backward inferencing process, a demand-chain process. In general, the goal objects generate the process to achieve their goals, instead of hard-coded processes as we too often see for example in BPM[xii].
The resulting object graph is able to perform one or more trees of business processes, where the roots of the trees are the final business results. However it is important to remark here that the object graph structure itself is not at all directly conceived from these processes. Instead, various, sometimes incomplete, processes are taken during the modelling phase to “play out” by existing and newly created objects. This leads to an object graph that can be validated to at least be able to perform the defined processes, but usually is able to perform a superset of these input processes. This can be seen in the modelling sessions, when the domain experts propose a new process, and we find out that the existing model is able to generate this process without needing any change whatsoever in the model.
The Time Inversion Pattern is one of the three primary patterns used in eXploratory Modelling (xM). Behaviour of objects is realised by thinking about the final goal of an object, and then to decide upon the last previous action needed to accomplish this goal. This final or last action is usually delegated to a new object (usually an Active Object), upon which the modeller jumps to this object, and tries to find out the previous action in this object in the same way. This process can be viewed in action in the subchapter containing an xM walkthrough.
This pattern is well known in industry, as exemplified by Toyota in what they originally called the Pull Model[xiii].
By using the demand-chain modelling strategy models gain in flexibility, especially in the case of uncertainty, vague business requirements, processes that are difficult to make concrete or should be highly optimised.
The resulting solution, the model, may lack structural consistency: models can be redundant and impossible to understand on an overall level. This is a potential problem, but we argue that in the case of the kind of model we talk about, this is usually not so. We create models that are complex, difficult to overview or comprehend, but because of the high cohesion this actually works in favour of the model instead of against it. The model is to a large extend managing its own complexity.
This pattern is usually combined with the Active-Passive Pattern, because the choice of where to place the previous process step to is determined by selecting an active object that is usually passive in the real world.
As mentioned earlier this pattern is well known and documented in supply-chain management theory[xiv].
An xM effort is not an island. It is embedded in a complete solution effort and should behave as a good citizen. It should not dictate the way software development is done, although as mentioned it operates most effectively in projects with certain characteristics such as agility.
To behave as a good citizen it should be interoperable. The Smalltalk environment may be used for the sessions, but the result should be, when necessary, transferrable to any other environment. Also the work of integration should not require high skilled or specialised labour, but be highly automated.
There are two aspects of interoperability we want to cover in this subchapter.
- Importing existing domain information
- Exporting into different programming languages and environments
We will only report those strategies that we have used in our own projects, since the purpose of this article is primarily an experience report. Much experience must still be gathered from others applying the method.
Importing existing domain information
For modelling a domain with domain experts it is usually necessary to “fill” the domain with objects they know. Having these objects to play with greatly helps in feeling “at home” in the domain and explore sensible processes and responsibilities. This filling, in order to be realistic, may often involve the creation of many thousands of objects. Often the classes for these objects do not exist yet, so how do we deal with this situation?
There may be alternative or better solutions, but what we have used in our projects was a very pragmatic approach. We asked the customer for access to their data. For one customer this data was too sensitive but it was not difficult to obtain a relevant data set in the form of an anonymised export of their Oracle data into a Microsoft Access database. This proved to be very useful. The dataset can be made available as raw data in Smalltalk, to be parsed and made into “real” objects with simple Smalltalk scripts.
This way we were able to create vast amounts of persons with extensive profile data which in this project was an important aspect of their domain and needed to be available in order to play with the domain effectively.
Exporting into other environments
MDA[xv] is working on an extensive set of transformation rules to enable model driven implementations. We have used a very restricted subset of this functionality, as was available in one of the tools we used, Enterprise Architect from Sparx Systems. This tool states it implements part of the MDA specification.
The part we used was XMI import, and transforming the resulting model into a C# implementation. XMI is part of the UML specification, and defines an XML interchange format for object-oriented languages.
We did not use (in fact these rules do not even exist yet) any transformation rules for transforming Smalltalk code into C#. This of course means that the resulting C# framework did not contain code either! We re-created the classes and methods. We did not re-create the method bodies. In that respect the resulting model does not bring us more than more or less traditional UML modelling.
However, we did export the Smalltalk method bodies. This was, together with all comment in classes and methods, placed into comments in the C# classes. A simple XMI framework in Smalltalk written by the author did the export.
Since we restricted ourselves to implementing in the domain classes only business domain behaviour, it is important to realise that the code in these classes has some interesting properties which help us a lot:
- Method bodies are typically short and concise, on average 2-3 lines of code.
- The complexity of this code is very low: they are typically easy to understand, because in fact they were created and written by the business domain experts, not by a programmer.
- Only a very restricted subset of the Smalltalk class library was used to write this code. This of course implied that for the facilitator only this restricted subset of the vast Smalltalk class library should be familiar
This helped us with our very simple strategy for transforming the Smalltalk codebase into C#: programmers needed basic understanding of Smalltalk, not much more, to read the Smalltalk code as comment in the C# classes, and manually transform this code into C#. And of course this implied that the resulting C# code in turn was simple as well.
The task turned out to be trivial, if somewhat time-consuming. But we concluded that for this task cheap or junior programmers could be used. It was a low-skill labour.
Other instance based approaches
Other approaches exist that have more or less overlap with xM. Some of them complement xM while others are similar. We give a summarised overview of some of these, in order to help in understanding xM better.
Used to get a feel for the required end product by creating simple examples, mock-ups or screen drawings. As a rule prototypes do not implement business logic or functionality because that would require too much time and effort, which had better be applied in implementing the “real” product.
- Use Cases
Describe typical interactions of users, called actors, with the system. No information is gathered on the components of the system, or the actual business processes in the domain that is under scrutiny.
- Scenarios or user stories
Sometimes closely related to use cases, but typically smaller or simpler. Used in so-called agile approaches. Basic planning input for extreme programming teams that gather them from requirements sessions with the customer, with the restricting requirement that they should be implementable within one iteration or sprint, typically with a duration of one to four weeks.
- Naked Objects[xvi]
Offers an environment that enables the user to “play” with objects and their state. Strong overlap with xM and the tools used in xM. Business domains that are more data-centric and form-oriented are well suited to tackle with Naked Objects. xM is more generic and better suited than Naked Objects to tackle complex domains.
- CRC sessions
Closely related to xM, in effect xM can be seen as derived from it. Originally conceived at Tektronix to teach object oriented thinking[xvii] , these workshop sessions actually play out objects and their interactions, and offer an effective technique to create high quality object models
xM in other environments
As was briefly mentioned in the article summary, the xM approach has been applied by the author and his colleagues in other environments, i.e. the VisualStudio development environment from Microsoft, using C# as the language to model/program in.
Programming languages like C# lack some features that can greatly increase the effectiveness of xM sessions. The same goes for the IDE, such as VisualStudio. This lack can partly be compensated by some modifications in the environment that we will describe here shortly. However we think the advantages of a modelling/programming approach like xM will bring sufficient benefits to justify its use even if external constraints prohibit a team from using the preferred Smalltalk environment for the effort.
- On-the-fly changing class names, method names and such, without needing to re-create existing instances (remember, xM sessions constantly extend and build on existing domain objects). This can be overcome by streaming the objects to file, and back again, with some recovery algorithms to deal with adding or removing attributes or changing names of attributes. For example the Object Bench in VisualStudio empties the objects when one of their classes is recompiled. However it is possible to hook into this and stream the objects out and in again.
- The ability to do this in several locations: in the browser, in the debugger, in the objects themselves
- Drag-and-drop to move objects around or create instances of associations (links in UML parlance) visually
We think xM is an approach that can introduce significant and relevant improvements in any development effort.
Though many of its composing elements are not new, and indeed have been part of the toolbox of most experienced and accomplished object-oriented modellers, the combination of techniques offers much added value.
xM is especially useful in a domain-centred architecture, that is an architecture that has a clear separation between the business domain and the other components. We think this separation is an essential design principle in any architectural style. A domain driven architecture has not been elaborated upon in this article, but this can be accomplished in many of the existing architectural styles architectures, such as a Service Oriented Architecture.
The use of this technique in our projects has been met with great enthusiasm by our customers, and indeed often been characterised as “we never thought this was even remotely possible to do with such ease and efficiency”.
[i] The author did not invent the term. It was first encountered at the ESUG 2007 conference in Lugano, in a presentation by Andreas Tönne (then from Georg Heeg eK, Germany). See NiallRossESUG2007report.pdf (application/pdf Object). [cited 29 May 2009]. Available from world wide web: http://www.esug.org/data/ReportsFromNiallRoss/NiallRossESUG2007report.pdf.
[ii] VisualWorks is one of several existing Smalltalk implementations. Cincom Smalltalk – Simply Possible. [cited 29 May 2009]. Available from world wide web: http://www.cincomsmalltalk.com/userblogs/cincom/blogView?content=vwfactsheet.
[iii] CincomSmalltalkWiki: Public Store Repository. [cited 29 May 2009]. Available from world wide web: http://www.cincomsmalltalk.com/CincomSmalltalkWiki/PostgreSQL+Access+Page.
[vii] Object Management Group – UML. [cited 29 May 2009]. Available from world wide web: <http://www.uml.org/>.
[ix] FOWLER, M. Patterns of enterprise application architecture. Boston: Addison-Wesley, 2003. (The Addison-Wesley signature series) has called this the Domain Model. The relation of this pattern to others can be seen in BUSCHMANN, F. Pattern-oriented software architecture : a system of patterns. Chichester ; New York: Wiley, 1996.
[xii] Edge Perspectives with John Hagel. [cited 2 June 2009]. Available from world wide web: <http://edgeperspectives.typepad.com/edge_perspectives/2005/10/from_push_to_pu.html.
[xv] “MDA.” http://www.omg.org/mda/.
[xvi] Welcome to Naked Objects. [cited 29 May 2009]. Available from world wide web: <http://www.nakedobjects.org/home/index.shtml.
[xvii] For an introduction on how CRC came to be, see chapter 4 in: BECK, K. Kent Beck’s guide to better Smalltalk. Cambridge, U.K. ; New York: Cambridge University Press, 1999. (SIGS reference library series 14).