Chapter 28. Future Task

Problem

A task is registered in the system at one point of time, although the actual performance of the task is to take place at some later time.

Characteristics: Very common in some domains. Advanced.

Keywords: Batch job, delayed performance, performance of job, postponed performance, registration of job, scheduling, time-ruled initiation of use case.

Blueprints

Future Task: Simple

Model

Model

Description

The Future Task: Simple blueprint consists of two use cases. The first, called Manage Task, registers the information received from the Task Definer about a task that is to be performed at a later moment in time. The second use case, Perform Task, is initiated by the Task Initiator at regular intervals. This use case models the selection of the task to be performed as well as the performance of the task. How the different variants of tasks are performed is described as alternative flows of the use case.

Applicability

This blueprint is used when the set of different kinds of tasks is quite small (fewer than four) and is unlikely to be changed, and if their descriptions are short.

Future Task: Specialization

Model

Model

Description

In an alternative blueprint, the Perform Task use case models the performance of a task in general. It is an abstract use case. The Perform Specific Kind of Task use case is a specialization of Perform Task. It describes how a specific kind of task is to be performed while inheriting the selection and initialization procedure of the task from Perform Task.

Applicability

This blueprint alternative is preferred when there are several different kinds of performances of tasks and when there is an explicit case for handling unknown task types.

Future Task: Extraction

Model

Model

Description

Another alternative is to let Perform Task be a concrete use case that selects the next task and then simply removes it. How to perform the chosen task is modeled in an extension use case that is inserted into Perform Task after the selection of the task.

Applicability

The advantage of this blueprint is twofold: It is easy to add new types of tasks to the system, and the descriptions of the extension use cases focus on the performance of the task and include nothing about the selection of the task. The disadvantage is that the description of what is to be done if the type of the task is not known has to be modeled in a somewhat awkward way (see the section Discussion).

Future Task: Performer Notification

Model

Model

Description

In this blueprint, the Manage Task use case notifies the Task Initiator each time a new task is registered or an existing task is modified. This means that the Task Initiator can keep track of when the registered tasks are to be performed. The Perform Task use case is initiated only when there are tasks registered in the system and not on just a regular basis.

Applicability

This blueprint is preferable when the tasks are registered or performed at very irregular intervals, or when the Task Initiator is based on an advanced scheduler.

Discussion

When an actor initiates a task in the system, the task is usually to be performed right away. In some situations, however, the task is to be performed at some later point in time. When that moment occurs, the system initiates the task, often after checking that the task is still due to be performed.

Discussion

A typical example of a task to be performed by the system at a time differing from when it was requested is a wake-up call. Such a call is ordered by a subscriber who dials a given number, enters the time the wake-up call is to be performed, and then hangs up. When the entered wake-up time occurs, the system will call the subscriber and, when the subscriber picks up the phone, it will play a message saying that it is a wake-up call.

Discussion

The exact time when the task is to be performed may be given by the Task Definer, but this is not the only way. It can, for example, be calculated by the system, or be guided by some external events. The Task Definer can also enter some constraint on a specific work task (for example, state that it must be performed before a certain time, or after the completion of another work task).

Another example is a work-task scheduling system, where the system calculates when the different work tasks are to be performed according to some algorithm based on the number of tasks to be performed as well as their priority and need of resources. Different individuals, be it persons or other systems, enter the different work tasks into the system, which then schedules them.

In the use-case model, how do we model the performance of a task that is defined at one moment in time and performed at another? A straightforward way would be to model it as one use case including both the definition of the task and the description of its performance. There are, however, some major drawbacks of this approach. The first has to do with the definition of use cases: A use case models a usage of the system. In a business-level model of the organization for which the system is to be modeled, one might say that ordering and performing a wake-up call is one usage of a telephone exchange business, and that scheduling and performing a work task is one usage of a task-oriented business. However, at the system level these are not atomic usages. When reading a use-case model of a telephone exchange, one would expect to find it explicitly stated that a wake-up call can be ordered as well as performed. Similarly, reading a use-case model of a work-task system, one would expect to find that a work task is scheduled at an earlier time than the actual time of performance. Hence, at the system level, the registering of a task is one usage and the performance of the task is another usage.

A second drawback has to do with rescheduling and canceling of tasks. Having ordered a wake-up call, one would certainly like to have the chance to cancel it. It must be possible to change the priority of a previously registered work task, so that another task with higher or lower priority can be performed before or after it, respectively. The rescheduling and canceling of a task is done within the system and it is therefore modeled by a use case. Because use cases do not communicate with each other, it is not possible for the rescheduling/canceling use case to inform the task use case that it is to be performed at another time than what was originally stated, or that it has been canceled.

Another aspect closely related to the rescheduling/canceling problem is that a use case should model the performance of some actions in the system. Now, imagine that the system is shut down for some reason (for example, maintenance purposes). Clearly, the execution of all the use-case instances currently present will then be stopped and the instances will disappear. However, the customers would not like to find that they never had their wake-up calls, or that their paychecks have not been issued, just because the system was shut down because of maintenance between the registration of the wake-up call and when the call is to be performed, or sometime between the registration of the work task to issue a paycheck and the time for the actual issuing.

The solution to the problem is simple. We model the scheduling tasks and their performance by separate use cases. Then there will also be separate use-case instances. This means that a new instance will be initiated when it is time for the wake-up calls and the issue of the paychecks, because at that time the system maintenance will be over and the system will be up and running again.

In other words, we should not model the registration and the performance of a task as one use case—we need two, as in the Future Task: Simple blueprint. The first use case will handle the registration of the task. This use case just receives the information about what task is to be performed and any specific constraints on the performance, such as its priority, at what time it must be performed, what tasks must be completed before this task, and so on. Then the use case calculates when the task is to be performed based on some scheduling algorithm and stores the task in a queue based on the calculation.

The use case might also inform a Task Initiator that there is a new task (see Figure 28.1). This notification, captured in the Future Task: Performer Notification blueprint, is optional and depends on how the Task Initiator is to be realized in a specific system. Often, the role of the Task Initiator is to be played by a predefined process in the operating system. This situation is often referred to as “use cases initiated by the system clock,” or “by the time,” and so forth. In other systems, the role of the Task Initiator might be realized by another system or even by a human being. This might be preferable if the tasks are to be initiated once or twice a day (for example, if there are batch jobs to be performed during the night, or if work orders are to be sent out each morning for the duties or tasks to be executed during that day).

The model of a task-handling system consists in principle of two use cases: one for registering tasks and one for performing them. Here, the Task Initiator is informed each time a task is scheduled.

Figure 28.1. The model of a task-handling system consists in principle of two use cases: one for registering tasks and one for performing them. Here, the Task Initiator is informed each time a task is scheduled.

The Perform Task use case models the performance of the tasks. It starts when it receives a notification from the Task Initiator that it should check whether there is a task to be performed at this time. The Task Initiator can do this on a regular basis or based on new information from the registration use case. The performance use case checks the queue for tasks that are ready to be performed and selects one of them based on priorities, available resources, and so on, and removes it from the collection and executes it. How the execution is done can be described by use cases that are specializations of the performance use case, by extension use cases, or by alternative flows in the use case (see Figure 28.2).

The Perform Task use case may either be specialized by or extended by other use cases that describe the performance of the specific tasks, or it may itself describe this as alternative flows.

Figure 28.2. The Perform Task use case may either be specialized by or extended by other use cases that describe the performance of the specific tasks, or it may itself describe this as alternative flows.

The latter procedure—as in the Future Task: Simple blueprint—is preferable if the model is to be kept small and there are only a few, predefined types of tasks, whereas the first two options are preferable if the model can be extended with new kinds of tasks.

In general, specialization (Future Task: Specialization) is a better alternative than extension (Future Task: Extraction) because it is easy to add an additional specializing use case handling the exceptional case when a registered task does not belong to one of the predefined kinds. This is not so easy to capture in the extension alternative, because the base use case must be independent of the extensions and therefore cannot contain a description of the exceptional case. The extensions must also be independent of each other, so it is not possible merely to add an extra extension use case called, for example, “Otherwise.” The solution to this problem is to add an extra extension use case, where the condition of the extend relationship captures the negation of the disjunction of all the other conditions. This must be done “by hand” by the modeler, and because the condition must be changed if another extension use case is added to the model, this is a major drawback.

In the generalization blueprint, the performance use case gives a complete description of the flow, although it abstracts away the details of specific task performances. In the extend blueprint, the base use case cannot include any description of the performance of the task; all of the performance is to be found in the extension use cases. In this case, the performance use case will therefore only select the task, remove it from the collection, and delete it. Nothing can be said about performing a task because this is defined in the extension use cases, and the base use case must be independent of these. This makes the base use case quite hollow. However, the advantage with the extend alternative is that it stresses that all cases will always perform exactly the same selection algorithm; it cannot be specialized in a child use case, because only additions are allowed using the extend relationship. Furthermore, this alternative allows the performance use case to select a collection of mixed tasks and then iterate over them. In the generalization case, only tasks of the same kind can be selected if a collection of tasks is to be selected and iterated over. Which one to choose depends on the situation. When in doubt, the best policy is to choose the generalization alternative.

Example

This section provides three examples of use-case descriptions: Manage Task, Perform Task, and Generate Invoicing Basis. The latter is an example of a specialization of Perform Task, and hence this is an application of the Future Task: Specialization blueprint. Because Manage Task also informs the Task Initiator about registered tasks, the Future Task: Performer Notification blueprint is also applied. Generate Invoicing Basis (see Figure 28.3) models how the information about all noninvoiced orders is compiled and sent to the Financial System actor, which represents an external system that is to receive the information.

The Generate Invoicing Basis use case is a specialization of the Perform Task use case and adds an association to the Financial System actor.

Figure 28.3. The Generate Invoicing Basis use case is a specialization of the Perform Task use case and adds an association to the Financial System actor.

See also the Business Rules, the CRUD, and the Commonality patterns, as well as the Message Transfer blueprints, which are all relevant to this example.

Analysis Model

The modeling of a task involves a collection of classes. First, we need to be able to handle information about the task to be performed, such as the name of the task and the time when it is to be carried out. This information is used when the execution of the task is initiated, but the information can also be reviewed and modified before the execution of the task, as well as be removed from the system if the task is canceled. We therefore need an entity class, called Task Information, which is responsible for modeling this kind of information; it represents a task that is to be performed in the future. If different kinds of tasks require different sets of information, this entity class is abstract and subclasses are introduced.

Second, we need a control class, Task Performer, to actually perform the task. This class captures how the execution of a task is to be performed; that is, it models the sequence or sequences of actions that are to be performed by the system. When the performance of a specific task is initiated, the Task Performer is instantiated and initialized with the relevant pieces of information stored in the entity object holding the information of that particular task. Subclasses of the Task Performer are introduced if the different kinds of tasks in our system are performed in different ways.

For each kind of task, there will usually be one entity class, modeling the information required to perform such a task and one control class modeling how such a task is to be performed. However, many kinds of tasks may require the same information about the task but will be executed differently. Similarly, what happens inside the system may be the same for different kinds of tasks, even though they operate on different information. We can therefore not presume that each kind of task will have its own pair of entity class and control class.

In cases where multiple subclasses of Task Performer could be used to execute a certain task registered in an instance of (a subclass of) Task Information, it must also be registered in the instance what subclass of Task Performer is to be used when executing it. Therefore, in the general case, when there is no one-to-one relationship between the subclasses of Task Information and the subclasses of Task Performer, there must be an association from Task Information to Task Performer referencing the class to be instantiated when the task registered in the (subclass of) Task Information is to be performed.

This leads us to the model presented in Figure 28.4. The Register Task flow of the Manage Task use case starts in the System Form where the Task Definer chooses to register a task. An instance of the Task Handler is created that retrieves a list of all possible performances—that is, what Task Performers are defined in the system. Then it presents the list to the Task Definer using a Task Registration Form. The actor enters the necessary information and chooses one of the Task Performers, which is then instantiated to request any additional information required for its performance. When the information is received from the Task Definer, a new instance of Task Information or one of its subclasses is created. Optionally, if the Future Task: Performer Notification blueprint is applied, the Task Handler then informs the Task Initiator via the Task Initiator Interface that a new task has been registered. Obviously, the registration can be done in the opposite order in the sense that the kind of Task Information is selected first. Finally, the registration use case ends.

An analysis model of a system for registering and performing tasks. The string {class} denotes that it is the associated class or a subclass of it that is to be attached to that end of a link; the absence of the string denotes the default case where instances are attached.

Figure 28.4. An analysis model of a system for registering and performing tasks. The string {class} denotes that it is the associated class or a subclass of it that is to be attached to that end of a link; the absence of the string denotes the default case where instances are attached.

The Perform Task use case starts on the Task Initiator's request. The request can be made on a regular basis or when needed as is the case when the time is sent to the Task Initiator from the Manage Task use case (Future Task: Performer Notification). An instance of Task Handler is created that checks whether there is a task to be performed and, if so, selects the task with the highest priority.

The Task Handler changes the state of the Task Information instance to active and requests which Task Performer subclass is to be instantiated from that Task Information instance. Then, the Task Handler creates an instance of that subclass of Task Performer. If it is required that all the tasks to be performed at this time are to be performed in parallel, no selection is made based on priority. Instead, the Task Handler iterates over the identified collection of Task Information instances and instantiates the appropriate Task Performer for each of them.

The instance of Task Performer is initialized with the instance of the Task Information, retrieves the required information from it, and starts performing the task in accordance with its own definition combined with the information retrieved from its Task Information.

If the task is successfully completed, the Task Information is removed, and the Task Performer removes itself. If not, the Task Performer registers the reason why the task failed in the Task Information instance and then it removes itself.

The model presented above is an example of control classes participating in the realization of more than one use case. Both the Task Handler and the Task Performer are involved in the performance of the two use cases Manage Task and Perform Task.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.185.221