Even though the UML is process-independent, its authors promote a process that is use-case driven, architecture-centric, iterative, and incremental. By understanding how the UML is related to process and the type of process the UML’s authors promote, you can better understand how to best approach learning the UML. However, any type of process—even one without these characteristics—may use the UML.
Generally, every system development lifecycle process involves the following types of lifecycle activities:
Requirements-gathering activities to capture requirements that define what a system should do
Analysis activities to understand the requirements
Design activities to determine how a system will satisfy its requirements
Implementation activities to build a system
Testing activities to verify that a system satisfies its requirements
Deployment activities to make a system available to its users
There are many types of approach for applying these activities to develop a system. Traditionally, a waterfall approach has been applied. Now, an iterative approach is more common.
When applying a waterfall approach, lifecycle activities are performed in a single, linear sequence for all the requirements. This often results in the discovery, during testing activities when the different pieces of the system are integrated, of quality-related problems that have remained hidden during the design and implementation activities. Because such problems are discovered late in the development process, it may be too late to resolve them or they may be too costly to resolve. For example, discovering that a specific database management system’s performance will be insufficient for the applications that use it after all of the applications have already been developed represents a colossal problem.
Consider a project that involves 10 requirements, perhaps the generation of 10 different types of reports where each report stems from a different requirement. Within a waterfall approach, all the requirements are captured and analyzed, and the whole system is designed, implemented, tested, and deployed in this linear sequence. Within such an approach, the UML may readily be used to communicate the requirements and description of the system. However, because activities are performed in a single linear sequence for all the requirements, the UML models must be fairly complete at each step. This level of completeness is often hard to measure or achieve, because while the UML is more precise than natural languages, it is less precise than programming languages. Therefore, rather than focusing on the system, teams using UML in a waterfall approach often struggle in trying to determine whether their UML models are complete enough.
When applying an iterative approach, any subsets of the lifecycle activities are performed several times to better understand the requirements and gradually develop a more robust system. Each cycle through these activities or a subset of these activities is known as an iteration, and a series of iterations in a step-wise manner eventually results in the final system. This enables you to better understand the requirements and gradually develop a more appropriate system through successive refinement and incrementally gaining more detail as you do more and more iterations. For example, you can investigate a specific database management system’s performance and discover that it will be insufficient for the applications that use it before the applications have been completely developed, and thus make the appropriate modifications to the applications or investigate using another database management system before it becomes too late or too costly.
Consider a project that involves generating 10 different types of reports. Within an iterative approach, the following sequence of iterations is possible:
We identify five requirements (named R1 through R5) and analyze three of the five requirements (perhaps R1, R3, and R5).
We capture five new requirements (named R6 through R10), analyze the two requirements that were not analyzed in the previous iteration (R2 and R4), and design, implement, and test the system that satisfies the three requirements that were analyzed in the previous iteration (R1, R3, and R5) and the two requirements analyzed in this iteration (R2 and R4), but we don’t deploy the system because we did not allocate enough time in the current iteration for that activity.
We deploy the system that satisfies the five requirements tested in the previous iteration (R1 through R5) and continue working on the other requirements (R6 through R10).
We continue working on the system but must address changes to one requirement that has already been deployed (perhaps R3), changes to other requirements that have not yet been deployed (perhaps R6 and R10), and other technical changes to the system.
This sequence of iterations may appear quite chaotic; however, an iterative approach is only a concept and the UML is only a language; thus, a methodology is required when using the UML on actual projects. When iterations are used by a methodology, they are not chaotic but are organized and quite dynamic within the context of the methodology.
An iterative approach to system development offers the following benefits:
We can better manage complexity by building a system in smaller increments rather than all at once.
We can better manage changing requirements by incorporating changes throughout the process and not trying to capture and address all the requirements at once.
We can provide partial solutions to users throughout the process rather than have them wait until the end of the process, at which time they receive the whole system and perhaps conclude that it is not what they expected.
We can solicit feedback from users concerning the parts of the system already developed, so we may make changes and guide our progress in providing a more robust system that meets their requirements.
An iterative process is incremental because we don’t simply rework the same requirements in successive iterations, but address more and more requirements in successive iterations. Likewise, activities may occur in parallel within a single iteration when they focus on different parts of the system and don’t conflict. Therefore, an iterative approach involves a series of iterations wherein the system is developed incrementally. Even though such an approach is often known as iterative and incremental, it is actually iterative, incremental, and parallel. Because such an approach gradually develops a system through successive refinement and incrementally increasing detail, we are better able to determine the appropriate level of completeness of our UML models than within a waterfall approach. For example, if we have a question or concern that needs to be addressed, and if we are unable to readily use our UML models to address that concern, perhaps we need to elaborate them further; otherwise, we can proceed without spending more time and effort elaborating our UML models.
With such a dynamic approach in which activities within iterations occur in parallel and a system is constructed incrementally, how do we keep our activities organized and driven to satisfy the requirements? How do we maintain focus on the system and avoid constructing a system that may be difficult to maintain and enhance because it is simply a collection of parts glued together without some overarching scheme? What requirements do we address first, and what pieces of the system do we implement first? Answering these questions is where use cases, architecture, and risk management are critical within an iterative approach.
A use case is a functional requirement described from the perspective of the users of a system. For example, functional requirements for most systems include security functionality allowing users to log in and out of the system, input data, process data, generate reports, and so forth. Use cases are the subject of Chapter 4.
A use-case driven process is one wherein we are able to use use cases to plan and perform iterations. This allows us to organize our activities and focus on implementing the requirements of a system. That is, we capture and analyze use cases, design and implement a system to satisfy them, test and deploy the system, and plan future iterations. Therefore, use cases are the glue between all the activities within an iteration.
Architecture encompasses the elements making up a system and the manner in which they work together to provide the functionality of the system. For example, most systems include elements for handling security functionality, inputting and processing data, generating reports, and so forth. The elements and their relationships are known as the system’s structure. Modeling a system’s structure is known as structural modeling. Structural modeling is the subject of Part II. The elements and how they interact and collaborate is known as the system’s behavior. Modeling a system’s behavior is known as behavioral modeling. Behavioral modeling is the subject of Part III. The different types of elements that constitute a system’s architecture, both structure and behavior, are determined by the object-oriented paradigm. The principles and concepts of the object-oriented paradigm are the subject of Chapter 2.
An architecture-centric process focuses on the architecture of a system across iterations. This allows us to better ensure that the resulting system is not a hodgepodge of elements that may be difficult to integrate, maintain, and enhance. Therefore, architecture is the glue between all the elements that make up the system as the system is incrementally developed across iterations.
A risk is any obstacle or unknown that may hinder our success. For example, when developing a system, risks include such things as insufficient funding, untrained team members with critical responsibilities, and unstable technologies.
To determine what use cases ought to drive an iteration and what parts of the architecture to focus on in the iteration, we first identify project risks. We then address those use cases that confront the highest risks and those elements of the architecture that, when built, resolve the highest risks. Such an approach is often known as risk confronting.
Consider once again the project that involves generating 10 different types of reports. Say that three reports (perhaps R1, R3, and R5) require significant database access, and that four reports (perhaps R3, R6, R8, and R10) require significant user input. Perhaps there are two risks: the risk of not having an intuitive user interface (named X1) and the risk of having an inefficient database management system (named X2). From these descriptions, we know that R1, R3, and R5 are associated with risk X1, and that R3, R6, R8, and R10 are associated with X2. If X1 is more critical to our project, and has a higher possibility of occurring or a higher impact on the project, we would address R1, R3, and R5 or as many of their requirements as possible first, because they confront risk X1. If X2 is more critical to our project, and has a higher possibility of occurring or a higher impact on the project, we would address R3, R6, R8, and R10 or as many of their requirements as possible first because they confront risk X2. However, in either case, we ought to target R3 first, because it addresses both risks.
The UML provides structural and behavioral modeling techniques that may be used in a step-wise process that is driven by requirements, focuses on developing an architecturally sound system that satisfies the requirements, and enables you to confront risks throughout the system-development process.
Get Learning UML now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.