In part 1, we tried to come up with a way to discover the services needed for a new application. The method we explore mainly uses the processes (or use cases) of the respective application, tries to take them apart into activities which are executed one after another. And then – looking closely at the activities – we find the services needed to get it implemented (or executed if you prefer).
Now, we will refine that approach and therefore, we will look at some more complex examples. The following process model depicts a use case called “create lost & found report”. In this process the user can enter data concerning an object found by the crew inside a plane. To help him fill in the data we need a service which gets all needed information about the current flights (flight numbers etc.). If the user is ready with the data he can hit the button “ok” and the system will create the lost & found report (a data record containing all the entered information). The activity where the report is created is depicted with white background color, meaning that this activity should be executed by the system without user interaction. This is important, for automatic activities often need information different than user-driven activities. Furthermore, the data returned by the corresponding service (e.g. the key of the new report) must be forwarded to another activity (“display”) because the automatic activity does not have a user interface. The forwarding is also depicted using an orange arrow. The GUI-less activity “print” which is always triggered after “display” does not need a new service, since it can benefit from the data already given back by the “create” service. It’s worth to note, that we differentiate between read-only and read-write services, which is shown as white or colored “lollipop” bubble, respectively.
But as you might have guessed, the processes can still become more complex. And we should now help ourselves by restricting us to the simplest use cases since that would probably hide some of the most interesting services from our analyses. The next process model below shows forks – locations where the process may take different routes depending on some decision. These forks, depicted as diamonds like in UML, are of special interest to us, since the decision which way to go nearly always depends on some data (or algorithm depending on data) which must be delivered via a service. In our syntax, we either need either a dedicated service to provide the necessary data (like “Get Configuration” in the example) or we can derive the information from the service executed by an activity closest before the fork (like “Search Report” which might deliver zero reports). This process model also shows a refinement activity (“Assign Report”), which again can contain a whole process of its own. We always use refinements like this in order to keep the readability of the model at a comfortable level. Another reason to use refinements can be to further reuse in the model itself, since “Assign Report” can be called in other process models as well. Another example of reuse – process switching – can be seen by the elliptic bubble at the top right (“controlling”) which stands for another use case. The user can decide to stop executing the current process at this point and continue in the “controlling” process instead.
As you can see, we have to enlist very sophisticated patterns of process modeling. But this is necessary if we really want to model all necessary use cases with the needed level of detail. If we wouldn’t employ refinement and process switching we would soon be lost in our processes and would not be able to continue with the real objective of our work – finding the services. Nevertheless, we are mostly done with describing the modeling technique. In the next part of this discussion we will turn to the questions left: But how can we be sure, if these services are at the right level of detail? How can we group and order them and how should they be developed and deployed?