Workflow: A Triumph of Hope over Experience
In response a previous blog entry, Gerald Loeffler raised a question about the potential relationship of Naked Objects to workflow or business process management (BPM).
I have always disliked both of those concepts for three reasons. The first is from technical perspective: they tend to encourage the separation of procedure from data and thus discourage good object-oriented design. The second is from a human perspectice: workflow and BPM systems tend to encourage a management philosophy that disempowers the users. I wrote about this in the original Naked Objects book back in 2002 and subsequently in my thesis.The third reason is that workflow, as generally conceived, simply doesn’t work! Recently I met with a workflow expert who works for one of the major systems integrators; to my susprise and delight he concurred with my assessment. He told me that in a very high proportion of systems that they install, the workflow element is completely switched off within a few months of the system going live. I asked him why his company continued to build workflow into new systems and he told me that it was invariably because the client’s management insisted upon it.What I mean by ’as generally conceived’ is building explicit representations of complex business processes or flows of work, and then running these scripts on some kind of engine that drives the tasks that individual users perform. This idea appeals hugely to management for two reasons: it allows the script to easily edited as the business organisation changes; and it gives the management better control and information about what is going on. In theory, that is. In practice this breaks down because real business processes are seldom capable of being 100% scripted, and as soon as you allow any kind of non-scripted variants the whole system breaks down. In The Social Life of Information (an excellent book), John Seeley Brown points out that the most valuable people in an organisation are those who’ve worked out how to get the job done for the customer, by overcoming the constraints of the formal business processes.However, I believe that there is a legitimate role for work assignment. Indeed I have designed several Naked Objects applications that involve a Task object. When the user logs on, they are presented with a ‘work list’ or ‘task list’. Each Task typically has a TaskType, a longer description and/or instructions, and, optionally, a Task Subject - the domain object (such as a Customer or Order), if one exists, that would be the starting point for the user to perform the task. Tasks may be assigned to an individual user or a team, and they may be transferred from one user or team to another. When the user has completed the task, they invoke the ‘Completed’ action on that Task, which records the date/time of completion, possibly one or more ‘completion options’ to record how it was completed, and then removes the Task from the worklist.
Sounds like worklow! So how does this differ from the approach I have just criticised? The distinction lies in what generates the Task. In the systems I have designed Tasks may only be generated by:
1. An explicit externally-generated event, such as the receipt of an email, or the scanning of an incoming paper document. The system can use this to generate a Task to deal with that event, and assign it to the appropriate team or individual - either based on a generic rule or on, say, the bar-coding on a scanned form. This, very limited, form of work assignment is indisputably an aid to productivity.
2. A user may generate a Task if they identify the need for an action that they cannot fulfill themselves there and then. In other words they can create a Task and assign it to a colleague, in which case the Task is acting rather like a structured email. Or they can create a Task to prompt themselves at a future point: e.g. bring [this object] back to my attention in 21 days, if nothing else has happened on it.
What these two design principles explicitly disallow is the idea that upon completing Task A, the workflow engine regains control and then issues Task B, either to the same user or another: the conventional notion of workflow. Rather, these two design principles reflect the fact that real business processes reside in the heads of the staff, and that is the best place for them.
So how do you stop things from falling between the cracks i.e. the user completes the first Task and then doesn’t continue to process a particular case? If this is a concern (and it need not necessarily be) one option is that all ‘purposeful’ objects (such as Case, or Order, or Enquiry) will have a status, such as ‘Active’ or ‘Completed’. It is a simple matter to run a periodic exception report, looking for all purposeful objects that have an active status (i.e. they should be being processed) and that do not currently have an associated Task that is assigned to someone, or have not had one for, say 24 hours. These can then be brought to a manager’s attention. Alternatively, the system could automatically send a reminder to the last person who marked a Task on that object as completed, asking them why they did not either create another Task, or move the purposeful object itself to a completed status. In my experience these situations do arise when the system is first used, but quickly die down once users get comfortable with the system.
I understand that all of this is a somewhat controversial view of business, but it is based on real experience. It reflects a very strong personal viewpoint that, to the extent that an information system involves human users, then the system should be designed to be the servant of the user, not the master. Most workflow systems attempt to be the master of the user.
Perhaps this is only tangentially related to the post, but …
I would like to get your view on an aspect of modelling that is relevant to both the Naked Objects pattern and other approaches. It is the question of when an “Event” should be considered an “Object” in its own right.
The perennial example of an Event that might be considered an Object is the “Transfer” event that moves funds from one account to another in a banking application. The issue here, of course, is that a Transfer affects two Accounts and it is therefore difficult to think of it as “belonging” to either of them.
However, affecting two objects seems not to be the sole criterion for making an event an object its own right, as you suggest (in the section “Dealing with the concept of process” of the Naked Objects book) that “Withdraw” and “Deposit”, which only affect one Account, should be similarly treated.
What about the “Open” and “Close” events for an Account? The first of these arguable affects two Objects: an Account, for which it is the creation event (assuming the Account was not initially brought in existence in a state “pending open” by an earlier event, as is the practice in some banks); and a Customer, for which the event adds another asset to the portfolio he/she owns with the Bank. Does the Open event belong to Account or to Customer? It would appear that, like Transfer, it should be separated from either by being awarded “objecthood”. Perhaps a similar argument can be made for Close.
In your PhD thesis, you address the possible need to award objecthood to events together with the idea of “Purposeful Objects”, suggesting (as I understand it) that the two concepts are linked. You say (page 32):
“Any business activity where the verb describing the activity can easily be mutated into a noun is a prime candidate for a purposeful object. Thus the users might have a requirement to “adjust” (verb) the prices. But they will also talk readily about “making price adjustments”. This phraseology should be a cue for thinking about PriceAdjustment as an instantiable entity object, rendered visible to the user (e.g. as an icon).”
Now I am a bit confused. Using “dual ownership” (like Transfer and, as I would argue, Open) as the criterion for awarding objecthood is a very different idea from the one suggested in this statement, which seems to associate the need for (or appropriateness of) objecthood with the way that the event is referred to in language. I suspect that this latter idea is based on a logical confusion, as for any event called “x” a user might talk about “making x happen”, where the first is the event and the second is the (purposeful) process required to action the event in the business, and should certainly be viewed as an object in its own right. However it is not right, in my book, to equate the business process “making a price adjustment” with the event “adjust the price”, only if because the process might determine that no price adjustment was warranted at all. To take another example: I might be “making a withdrawal” from my bank (and here a process has been instantiated), only to find that my account is overdrawn and I cannot take any money out (so the withdraw event itself is not instantiated). So processes can, in this sense, fail to “mature” into an actual business event. But I believe it is the *process* that is purposeful and not the *event*.
If we accept this distinction (between processes and the events that may result) then “Withdraw” and “Deposit” (the events, not the associated business processes), as they do not affect multiple objects, should be stripped of their claim to objecthood.
Is this a correct analysis?
You use the term ‘Event’ somewhat differently to the way that I use it in my modelling. I use it in a rather narrower sense. To me an ‘event’ is a notification that something has happened somewhere OUTSIDE the system that you are modelling, such as ‘Customer Has Died’, ‘Order Has Been Cancelled’. Those events are notified to the system you are modelling, via some mechanism such as Publish & Subscribe, to which something in the model might or might not respond. Although the notification of that event might be wrapped up in an object for technical reasons, these events don’t feature as objects in the model.
So, if I was writing a banking system where I was providing specific functionality for opening accounts, making withdrawals and/or transfers, I would not personally refer to Open, Withdraw or Transfer as ‘Events’. But that does not alter the gist of your question, how are those requirements best represented? For the case of withdrawing funds from an account, I see three choices:
1. Withdraw is a method (verb) on the Account object
2. Withdrawal is an object in its own right
3. The functionality to effect a withdrawal exists outside the domain object (entities), in the form of some kind of script or controller.
The third option is the most common implementation by far, but is not an object-oriented solution at all. I think you are well familiar with this argument from having read my thesis. To me both 1 and 2 are potentially acceptable solutions. I would favour solution 2, though, and the criteria for this is: is it likely that we might want to refer specifically to a certain withdrawal, after it has happened (i.e. ‘No, not that withdrawal, *that* withdrawal’). And if we are, might we want to be able to invoke behaviours on it. Two good examples of the latter are ‘credit [this withdrawal] back’ (as happened to me recently when an ATM did not in fact give me the cash), or ‘Charge a transaction fee [for this withdrawal”. To me this is a clear case for the object. If you can’t see any such need, then ‘withdraw’ can simply be a method.
The issue about involving more than one object is a bit of a red herring, I feel. To me the argument for making Transfer an object is the same as for Withdrawal, not because Transfer involves two objects. Whether or not you represent a transfer as a persistent object in the model, you still need to have a method for initiating the transfer. And in the Naked Objects philosophy, this method should be on the Account object. The question is whether in executing that method it creates a Transfer object and associates that with both of the accounts, or just makes the debit & credit (which could also be objects). If you do it purely as a method, then the transfer method needs to take the other Account as a parameter. If you use the Transfer object then you have the option that the transfer method can return a transient Transfer object with the from Account populated, to which the user then supplies the ‘to’ Account and invokes a ‘do it’ method on the Transfer. These last points are very relevant if you’re intending to use Naked Objects, but not hugely relevant if you’re not.
I hope that helps a bit. But at the end of the day, I’m not sure we’ll ever resolve our differences, Ashley. You have your own modelling representation that makes heavy use of events. Personally, your representation does not resonate with me. I also don’t think yours is really an object-oriented representation at all: it is an event-transition representation. But that doesn’t make my approach right and yours wrong. I originally read Engineering Science at university, and 90% of the degree seemed to be about considering alternative representations for the same problem space (Laplace transforms, z-transforms and so on). I think that the approach I’ve advocated is gaining a lot of ground, particularly with advent of the Domain Driven Design movement (with which it is very compatible). But new representations emerge all the time: Aspects being in the ascendancy right now.
All the best,
Richard
Richard,
i strongly sympathise with your aversion against “command-and-control”-type management, but i’m afraid that this (rather then true employee empowerment) still is the dominant form of management - regardless of how Naked Objects deals with business processes and workflows.
the fact that business processes are contested at all is because they essentially comprise the true value of an information-oriented business - hence the urge for managers to get them under their control (often with sinistre intentions).
the use of a “Task” object as you describe it is the ad-hoc creation of an element of business processes. nothing inherently wrong with that.
but you *do* lose the other elements of business processes and workflows that can be very useful:
1. the fact that a business process is a very useful scoping mechanism: some entities (aka process variables) are needed during the course of a business process (and need to be persisted because the process is long-lived) but not afterwards.
2. the fact that a business process is a state machine that is a very effective means of capturing/communicating the more coarse-grained flow of information and control amongst objects (or services; but i guess you don’t like that word). your use of “Active” and “Completed” also strongly points into that direction. just like you did it with “Task” it’s probably quite straighforward to create a “BusinessProcess” in an ad-hoc fashion with Naked Objects…
3. contrary to your statement that business processes “do not work in practice” i would argue that many processes do have a very useful default flow - the default transitions in the state machine that the process is. many users may be thankful for a “now proceed as usual”-button that essentially tells the business process to take the default transition. i suppose your argument about business processes “not working” is an argument against to rigidly defined processes transitions.
i must confess that i don’t know how this fits with Naked Objects, other then having a hunch that it is somehow missing as a higher abstraction above the domain model and that Naked Objects and it’s “reflective” UI could very well make good use of workflow-related features, as hinted at above…
regards,
gerald
Gerald
I am very familiar with these arguments, and I accept that far more people would agree with your position than with mine.
In particular, most people would agree with your statement that ‘business procss is a very useful scoping mechanism’. After all, almost every methodology, from waterfall to agile, is ‘use-case driven’. But I do not agree with this. Use-case driven analysis leads to poor object modelling in my experience. My position on this is that use-cases should be used to validate the object model, not to identify it. That is a subtle but very important distinction.
I have been in several situations (some documented in the book), where there has been a very strong pro-process lobby. Indeed I have been many times told that ‘you can’t possibly model the business without starting from the business processes’. Or that ‘the business processes fundamentally ARE the business.’ But we have, and we have succeeded. The DSFA will confirm that we designed and built their complete Common BOM without anything that resembled a business process representation. When we were done, another consultancy came in to do the change management programme, and the first thing they did was draw enormous process diagrams that covered the whole wall of a large room. It added no value and was never ultimately used. In fact the DSFA’s own conclusion was that this was a much weaker representation of the essence of their business than the BOM itself.
You are not the first person to suggest that the Naked Objects concept could be applied to a (process-like) ‘higher level abstraction’, but I’ve yet to see anyone do it. If you do decide to go ahead with it, I would, of course, be very interested to see the results.
Richard
i remember having read in a recent infoq interview with you that Naked Objects is one of the most opinionated java frameworks out there. reading your reply i can now see that this not only applies to Naked Objects itself
…and it think that diversity of memes is absolutely necessary for progress!
Richard
Many thanks for your comments.
> You use the term ‘Event’ somewhat differently to the way that I use it in my modelling. I
> use it in a rather narrower sense. To me an ‘event’ is a notification that something has
> happened somewhere OUTSIDE the system that you are modelling, such as ‘Customer Has
> Died’, ‘Order Has Been Cancelled’.
I view events exactly in this manner. I don’t think we differ here at all. However the names you use: “Customer Has Died”, “Order Has Been Cancelled” are really names of states, of Customer and Order respectively. You can tell that they are states because they persist: the predicate “Customer has died” remains true through time. The corresponding event names are, I hope you will agree, “Customer Dies” and “Someone Cancels the Order”; and these are not persistent predicates, so not states.
> So, if I was writing a banking system where I was providing specific functionality for
> opening accounts, making withdrawals and/or transfers, I would not personally refer to
> Open, Withdraw or Transfer as ‘Events’.
Can you tell me what you would regard as “events” in world of Accounts? Surely “Close an Account” is not that different from “Cancel an Order” (which you give above as an example of an event)? They both represent business decisions that result in change to the state of an object represented in the system.
> The issue about involving more than one object is a bit of a red herring, I feel.
Good. I agree with that.
> Personally, your representation does not resonate with me.
That’s a pity - as many of our ideas are very similar. In particular, we agree on the main point: the desirability and feasibility of eliminating the “Controller” layer. Perhaps what we are doing is “Naked Events”?
> I also don’t think yours is really an object-oriented representation at all: it is an
> event-transition representation.
This is a comment I don’t understand. The event-transitions are used to model object behaviour, in a good object-oriented way. There are certainly differences between “standard” O-O and what we have been doing, relating mainly to the inheritance model. We have (for very good reasons) adopted a pure mixin approach to inheritance, rather than a hierarchical one. This comes very naturally from our use of CSP (per Tony Hoare) composition as the means of combining partial behavioural descriptions. Other than that, I think we are pretty much in line with O-O.
> I originally read Engineering Science at university, and 90% of the degree seemed to be
> about considering alternative representations for the same problem space (Laplace
> transforms, z-transforms and so on).
Mathematics myself (Cambridge). So we have similar background here, and I understand what you are getting at.
> I think that the approach I’ve advocated is gaining a lot of ground, particularly with
> advent of the Domain Driven Design movement (with which it is very compatible). But new
> representations emerge all the time: Aspects being in the ascendancy right now.
Indeed. CSP based composition applies very nicely to modelling stateful (behavioural) aspects. And CSP composition allows local (modular) reasoning across composed behavioural descriptions, which in my book is “a must” if you are to retain intellectual control over complexity in the world of Aspects.
I think we both aim to address DDD.
All the best,
Ashley
Your question confirms my view that we do view events differently, but I don’t think I explained my concept very well. What I meant by ‘CustomerHasDied’ is that somewhere else in the system (or another system) the fact of a customer’s death has been processed (i.e. presumably on the Customer object). This change is then broadcast (e.g. via P&S) as an event to other objects that might be interested (e.g. schemes paying benefits) which might or might not then act upon that event. So, in other words, I am not modelling the real-world event of the customer dying, I am modelling an internal event - effectively a broadcast message. Perhaps it would be clearer if I called my event CustomersDeathHasBeenRecorded - I was making up the example on the fly! My example of OrderHasBeenCancelled added to the confusion: what was in my mind was that this event was generated by another system, on which the order had been cancelled, and this was being notified e.g. to the credit-control or manufacturing systems.
To me Cancel is a method on Order, and withdraw is a method on Account (whether or not they create Cancellation or Withdrawal objects in the process). I understand that you model cancel and withdraw as events, but I just can’t think of events that way.
My comment about your approach not being OO was possibly too strong - but as you say it is not standard OO. (Ironically, I do think of Naked Objects as being just plain old OO - even though everyone else seems to think its very radical!). I certainly don’t have any problem with AOP or the approach of inheritance by mixin instead of by hierarchy - that fits very well conceptually with Naked Objects, though we haven’t really used AOP in anger yet.
I guess it is just this Events thing that is the real blocker for me. Incidentally, there is no Event concept in Eric Evan’s Domain Driven Design - the word doesn’t even feature in the index. Not that I consider DDD to be any kind of definitive reference (though an increasing number of people seem to) -to me it is just an aspirational idea plus a number of very specific patterns.
I will, however, order and read your book.
Richard
Hi Richard
I think I understand your difficulty with “events” better now.
I think my comfort with the notion of event stems from my background in modelling (JSD, Syntropy, Catalysis, etc.) and process algebras (CSP, CCS, etc.) where the concept is well embedded.
It doesn’t have a counterpart in OO programming, so you have to represent an event (in the modelling sense above) as either a method or an object. If this your background/focus, the concept of “event” is probably a bit alien.
Rgds
Ashley
P.S. I haven’t written a book — but perhaps it’s a good idea!
Yes, exactly. I have never used process modelling tools or process algebras, although I do have a basic understanding of those approaches.
When I’m working with clients, we strive, DDD style, for an ubiquitous language, where everything in that language translates, very directly, into a construct in the final code — as you say, into an object, or a property on an object, or a method. The fact that I have done this on a large scale, and large complexity business models, without ever coming across the need to model an event (in the sense that you use it) combined with the fact that such things wouldn’t anyway translate into any distinct construct within the target (OO) technology platform, is why I can’t see any value in introducing them. (Note that the applications we work on don’t always end up running on Naked Objects - sometimes we are using that just for the prototyping - but they do always end up being OOP).
I have not (at least in recent years!) fallen into the trap of claiming that pure OO is the only correct (or even the ‘natural’) representation of the real (business) world. Just that I have found it to be the most effective.
If the target platform was one in which Events (in the sense you use them) were tangible software constructs, then, of course, it does make sense to seek to capture requirements in terms of events. One of the issues I have with your concept, though, is that it is a tool for simulating the final system. I think your argument would be more powerful, if, as with Naked Objects, the modelling exercise led directly into the delivered system, with full round-trip modification. One of the big advantages we have is that we are effectively modelling in a language (can be Java or C#) that is ultimately capable of implementing, reasonably well, all the requirements of a business system. My concern about process/event language is that, even though it can be proven at a theoretic algebraic level that they can model all requirements (as can a Turing machine), in practice they are not considered to be comprehensive programming languages. So you end up having to augment your process/event language with implementations in, what shall we call it, a ‘pragmatic’ programming language.
I think if you have built systems that have a concept of an atomic unit of update that result in a move from one coherent (i.e., business meaningful) state to another, then you have implemented what I would call events — whether that’s the name you use when you model/design them or not.
I think my main reason for advocating events as distinguished primitives of design/modelling is the power this gives in terms of composition, and therefore abstraction and reuse, of behaviour (see http://www.metamaxim.com/download/documents/OEPM.pdf ). I haven’t seen anything like this built from the standard notions of OO programming (objects, methods, properties and hierarchical inheritance).
> One of the issues I have with your concept, though, is that it is a tool for simulating
> the final system. I think your argument would be more powerful, if, as with Naked
> Objects, the modelling exercise led directly into the delivered system, with full round-
> trip modification.
That’s a fair comment. But I don’t think it is an issue with the *concept* so much as our particular current implementation of it. I see no reason in principle why what you propose could not be done — although how best to do it is another matter!
Rgds
Ashley