EXAMPLES OF SOFTWARE DEVELOPMENT PROCESSES A. ICONIX Process (see. Curs7.ppt) Example taken from Applying Use Case Driven Object Modeling with UML: An Annotated e-Commerce Example by Not Specified Publisher: Addison Wesley Professional Pub Date: June 14, 2001 ISBN: 0201730391 Pages: 176 Slots: 1.0 At http://acmsel.safaribooksonline.com/ Application: INTERNET BOOKSTORE 1. Class Diagram for the Domain Model 2. Use Case Diagram 3. “Search by Author” Use Case Case - Search by Author 3.1. Use case description Basic Course The Customer types the name of an Author on the Search Page and presses the Search button. The system ensures that the Customer typed a search phrase and then searches the Catalog and retrieves all of the Books with which that Author is associated. The system retrieves the important details about each Book and creates a Search Results object with that information. Then the system displays the list of Books on the Search Results Page, with the Books listed in reverse chronological order by publication date. Each entry has a thumbnail of the Book's cover, the Book's title and authors, the average Rating, and an Add to Shopping Cart button. The Customer presses the Add to Shopping Cart button for a particular Book. The system passes control to the Add Item to Shopping Cart use case. Alternate Courses If the Customer did not type a search phrase before pressing the Search button, the system displays an error message to that effect and prompts the Customer to type a search phrase. If the system was unable to find any Books associated with the Author that the Customer specified, the system displays a message to that effect and prompts the Customer to perform a different search. If the Customer leaves the page in a way other than by pressing an Add to Shopping Cart button, the system returns control to the use case from which this use case received control. 3.2 List of Associations Customer Communicates with Search by Author 3.3 Robustness Diagram for “Search by Author” Use Case 3.4 Sequence Diagram for “Search by Author” Use Case B. Larman's UML Process Use Cases Define user interaction with the system. Underline nouns to identify concepts in the problem domain. Conceptual Model Use the underlined nouns from the use cases to create the concepts in the conceptual model. Some of the nouns, if they identify simple data types, are used to create attributes of these concepts. Create associations between the concepts. System Sequence Diagram Create system sequence diagrams for each use case scenario. Each sequence event in the diagram corresponds to a user interaction with the system specified by the expanded use case. System Contracts Specify post-conditions for each system event in the system sequence diagrams. Use the conceptual model to identify objects created, associations formed, and attributes modified. Collaboration Diagram Create a collaboration (or sequence) diagram for each system event in the system sequence diagrams. Assign responsibilities to classes in the conceptual model to fulfill the post-conditions in the contracts. Use associations from the conceptual model in conjunction with patterns (Expert, Creator) to assign responsibilities. Class Diagram Add methods and additional attributes which were discovered in the collaboration diagrams to the classes in the conceptual model. Code Create classes with their names, attributes and method signatures taken from the class diagram. For each method on a class, use the collaboration diagrams to find the sequence of messages generated when the method is called and create at least one line of code for each message. C. Discussion on UML Diagrams Relationship between UML diagrams All other diagrams feed information to the Class diagram. Apart from the Component and Deployment diagrams, which are used to describe the implementation environment, all the diagrams model facts at the object level. These facts come from test cases and examples that help us understand how things work. Facts are invaluable resources, but to build a software application the modeler has to create a set of abstractions, rules, and concepts that describe how these facts may be used. The abstraction needs to define what each resource is, the information it owns, what it can do, and the other types of resources with which it needs to interact to do its job correctly. The next figure represents how the UML diagrams uncover facts that support the creation of the Class diagram. The Class diagram models the facts so that the model represents reality as closely as possible. The Class diagram defines the code that generates the objects. The objects conform to the Class diagram. Figure: The relationships between the Class diagram, other diagrams, and the application code. The other UML diagrams model facts as objects. These objects either conform to the rules set forth in the Class diagram, or they reveal the need for corrections to the rules. The rules in the Class diagram are used to generate code. The code generates objects, while the application is running, that behave according to the rules defined by the Class diagram. Systems may be fairly complex and may require more than one Class diagram. In fact, it is very common to break a subject area down into a set of smaller Class diagrams. Smaller diagrams are easier to work with and easier to verify. But no matter how many diagrams you use for the system, each class has only one definition. A class represents the same concept no matter where or how often it appears in the diagrams. In a modeling tool, this is accomplished by using a repository. A repository is a shared dictionary, usually built into the modeling tool, of all of the information defined during the modeling process. The first time you add a class to a diagram, a definition is placed into the repository by the tool. Each subsequent time that the class is referenced on a new diagram, the new reference is associated with the existing definition. Consequently, a change made to a class on one diagram is also made to the class definition in the repository, and is reflected in all diagrams that include that class. Defining all of these rules sounds quite complicated. In truth, the notations of the Class diagram provide a surprisingly simple yet powerful means to specify everything needed to generate code. With rigor and the proper software support, the Class diagram can even become fully executable. This means that the model can be tested by executing scenarios and can even generate the complete application in a variety of implementation environments. Attribute type discussion During requirements gathering, the data type captured in the attribute definition should reflect the clients' expectations, external view. The design-level version of the model should replace the external view with the internal representation. This is one reason the version control is so important for the modeling process. The external view identifies the form that the value takes as input and output. The designlevel definition defines the internal storage requirements. The accessor methods, the operations used to put the data into the object and take it back out of the object, are responsible for the translation between the two forms. D. Summarization of RUP (Rational Unified Process) approach Extract from: Chapter 14 - Modeling the Application Architecture UML Bible by Tom Pender John Wiley & Sons © 2003 How to Organize Your Packages You categorize models of a real-life system with a combination of «model» packages, subpackages, subsystems, and components. The ways to organize your work are limitless. The UML specification does not provide a method for categorizing your work. There are a number of published methods you can follow such as the Rational Unified Process (RUP), Catalysis, Shlaer/Mellor, the ICONIX Unified Object Modeling Approach, and others. In addition, many organizations have developed their own approaches to categorizing and building models. As a representative example, this section provides a high-level summarization of the RUP approach to organizing your work with packages and subsystems. The RUP offers a step-by-step process for analyzing, designing, implementing, and testing systems to support the processes of a business. This section focuses on creating packages for the Use Case, Analysis, and Design models. Creating the Implementation and Testing models is considered outside the scope of this book. Establishing the Models and Views At the highest level, you use models to categorize your business systems. According to RUP, you build models to support the following views: Use Case Model for the Requirements View. Presents the business analysis and contains all of the Use Cases that describe the functional requirements of the business domains. Analysis Model for the Analysis View. Includes packages containing a mixture of UML diagram types that describe how the systems of the business are logically constructed. Design and Deployment Models for the Design View. Contains subsystems, components, and design classes that represent the design of the system. If you are following OMG's Model-Driven Architecture, the Design Model does not provide platform-dependent details. It is a further refinement of the Analysis Model and differs from it in how you name classes (for example, remove embedded spaces from less formal analysis class names), and how you structure classes and components together to address design constraints. Implementation Model for the Implementation View. Contains models representing the actual implementation of the systems that support the business. This model also contains the actual code and databases that comprise the systems, which means that some of this view is contained outside the modeling tool. Testing Model for the Testing View. Contains the test models for the systems that were built to support the business. A test model is a collection of test cases, test procedures, and test components that describe how the artifacts of the Implementation Model can be tested to see if they conform to the requirements put forth in the Use Case Model. The Testing Model is generally housed outside of a modeling tool. Step 1: Building the Use Case model You begin the RUP by establishing all of the use cases for your business. The use cases represent the functionality that the systems of the business provide to external customers. You model the use cases in terms of how the customer, or other external actors, sees the system. You provide a description for each use case, and in so doing use the language of the customer. This is typically a flat view of the system from the customer's perspective. There is no real need for you to group the use cases into packages, since this would reflect how the business is arranged, and the customer does not see this. Step 2: Building the Analysis model During analysis you look at the system in terms of how you will build it. Instead of using the language of the customer, you use the language of the developer. You start analysis by categorizing your use cases into packages that reflect the structure of your business. Reexamine the use cases to add details necessary to actually implement them, and while you are doing so, you find the analysis classes of the system, and their relationships to one another. Perform architectural analysis Begin with architectural analysis, wherein you group the use cases into packages. You can physically place a copy of all use cases into the Analysis model. Put use cases that provide related functionality—those that are involved in the same business process, or that communicate with the same actor, or that are related to one another through extend or generalization relationships, for example—together in a package. Figure 14-12 shows example use cases for a hotel business grouped into packages for Room Reservations, Conference Room Bookings, and Rewards Program Administration. Figure 14-12: Initial packaging of use cases during architectural analysis. Once you establish a first cut of your packages, you refine those packages to make them strongly cohesive and loosely coupled. There is a fine art to making a system properly cohesive and coupled. You componentize the system so that you can replace functionality in the future by simply replacing a package. You build a set of packages that are coupled together. At the same time, try to make each package strongly cohesive so that it doesn't depend on too many other packages. Too many dependencies means that a change to one package will ripple to any package that depends on it. There are three techniques for refining packages. First, examine the packages to see if there are use cases or classes that exist in multiple packages. If there are, think about reducing this commonality by breaking those use cases out into their own package. This loosens the coupling of the packages and helps keep future changes localized to one package. Second, see if there are any packages with use cases that perform a basic service to other packages. These are considered service packages. You may have a use case with associated classes in one package that works together with a use case and associated classes in another package to perform a service. Group these use cases together in one package and let other packages use its services. In the hotel example shown in Figure 14-3, the Accounts Payable package includes the use cases Check Customer Credit and Invoice Corporate Client. It is a service package. Creating service packages is another way to loosen the coupling of packages to provide reuse and localize future changes. Third, evaluate the dependencies between packages. Keep package dependencies at a minimum, so that a change to the functionality of a package doesn't require that changes be made to dependent packages. If a package has use cases that are more strongly related to use cases in another package than the ones in their own package, move those use cases to that package. This improves cohesiveness. Aim for cohesive packages in which the use cases are strongly related. During architectural analysis, you also examine the system for special requirements, which encompass features like on-line security, distribution of the application, persistence of classes, and transaction management. Create packages for each of these special requirements. In Figure 14-13, packages for database access and on-line security are added. Figure 14-13: Regrouped packages. Analyze use cases. During this stage of the RUP, examine each use case to determine how it will be realized. Examine each use case description with an eye on modifying it to add details that are necessary to implement it, using the language of the developer. A use case that has been modified in this way is referred to as a use case realization and is often denoted by changing the use case's look to that of a dashed oval. Then "walk" each use case description, and model the analysis classes necessary to make the scenario happen, developing boundary, entity, and control classes on a class diagram for each use case. This is sometimes referred to as robustness analysis. The ICONIX Unified Modeling Approach can be used in conjunction with RUP at this point. The ICONIX approach adds some important constraints to remember during this analysis that will help you understand the problem at hand: An actor (drawn as a stick figure) can only talk to a boundary class (drawn as a circle with a vertical bar attached to its left side). A boundary class can only talk to an actor or control class (drawn as a circle with an arrow drawn in its upper right corner), not directly to an entity class (drawn as a circle sitting on a horizontal bar). An entity class can only talk to a control class. Figure 14-14 shows some of the analysis classes found by walking the use cases in the Room Reservations, Conference Room Bookings, Rewards Program Administration, and Accounts Payable packages. Figure 14-14: Robustness analysis yields analysis classes. Analyze classes Analyze each class modeled to determine its responsibilities to the system, its attributes, and its relationships to other classes. Refine your models by adding this information to them. Build associations between classes and add generalization relationships. Refine analysis packages Finally, reanalyze your analysis packages to ensure they are as cohesive and loosely coupled as possible. If there are any classes that perform most of their duties in a different package than the one they are in, move them to that package. In the hotel example, the classes in the Conference Room Bookings package are highly dependent on the Room Reservations package. There is no real reason why we need a Conference Room Bookings package. To reduce dependencies and make the Room Reservations package more cohesive, we eliminate the Conference Room Bookings package and move its classes to the Room Reservations package, as shown in Figure 14-15. This figure shows the classes in their regular, rectangular form, rather than the iconized form based on their stereotype shown in the previous figure. Figure 14-15: Analysis packages for hotel. Step 3: Building the Design model After analysis, you move on to design, during which you group design use cases and classes into subsystems. The design subsystems are grouped into a Design View model, which, as you saw earlier in this section, is a package of stereotype «model». Perform architectural design As a first step to architectural design, create a subsystem that corresponds to each analysis package. Then, refine those subsystems. One technique for refining the subsystems is to establish the physical machines, or nodes, and network configurations on which the systems will run. Use UML Deployment diagrams to model a first cut of the configurations, and then map subsystems against the nodes on which they will run. In the hotel example, the Room Reservations system can be broken out onto the client machine and a dedicated Web server, so break it into two subsystems: Reservations UI, which resides on the client, and Reservations System, which resides on the Web server. This is shown in Figure 14-16. I also break up the Accounts Payable subsystem, since it becomes obvious at this point that Credit_Card_Account and related classes will exist on external bank servers, while Corporate_Account is located in a subsystem housed locally, probably on the Web server. Figure 14-16: Mapping subsystems against physical deployment nodes. The Rewards Program Administration system will also reside on the Web server. The Database Access system will reside on a Back Office server. We don't need to make specific decisions about the database brand, such as SQL Server, Oracle, or DB2, or about the implementation language or middleware of the system, such as JDK or .NET, at this point. These choices are made later during implementation. In following the MDA philosophy, analysis and design models are kept independent of technology choices. Once the first cut of subsystems is established, you loosely set up how the subsystems are connected together using dependency lines. You then add design details to each subsystem. Start by using UML notation to divide each subsystem into a «specification» and a «realization» compartment. Fill in the «specification» compartment by modeling what the subsystem should provide. You can use various UML artifacts, although Use Cases, Activity diagram flows, and interfaces are typically used. Then denote how the specification is fulfilled by adding details to the «realization» compartment. Design use cases Just as you walked the Use Cases during analysis to find analysis classes, now walk the Use Cases in each subsystem to establish the design classes necessary for it to work. During this phase, pay particular attention to how the Use Case will be implemented in a physical system. Use the classes established during analysis as a guide to creating the design classes. Be sure to remove embedded spaces in class names, because most programming languages do not support them (even though, at this point, you are not necessarily specifying a programming language). Use Sequence and Collaboration diagrams to get a better understanding of how the objects of classes interact. As you establish the design classes, place them in the «realization» compartment. These are the classes that implement the subsystem specification. A subsystem is a type of component. As such, it contains functionality that is presented to the outside world in the form of one or more interfaces. Examine each subsystem to establish its interfaces. For the hotel business example, I use Use Cases to show the specification of each subsystem, and the classes that implement those specifications in each subsystem's «realization» compartment, as shown in Figure 14-17, and begin establishing the interfaces of each subsystem as a lollipop symbol emanating from each subsystem symbol. Figure 14-17: Hotel reservation subsystem with «specification» and «realization» compartments and interfaces. Design classes To continue with design, identify each class's operations, attributes, and relationships to other classes. During this stage, model aggregations and inheritance. You may use State diagrams to model classes with interesting dynamic behavior. Refine subsystems Toward the end of design, take another look at the subsystems to see if they can be refined, so that they are as cohesive and loosely coupled as possible. Inspect each subsystem to see if it is as independent as possible of other subsystems and that it provides the functionality denoted in its «specification» compartment. Step 4: Building the Implementation model After design, you move on to implementation, during which you specify platformdependent details of the system. You specify these details using Component and Deployment diagrams, and group the artifacts in an Implementation model. Step 5: Building the Testing model You build the Testing model by creating test cases that specify what to test, and test procedures that specify how to test the systems you are implementing. The test cases are derived from the use cases of the Use Case model and use case realizations of the Design model. These test cases, test procedures, and corresponding test results are performed and housed outside of a modeling tool, but can be traced back to the models. An in-depth discussion of testing is outside the scope of this chapter. Overall Hierarchy of Models In the example in this section, I have presented all artifacts drawn within package or subsystem symbols. If I were using a modeling tool, I would create my model, package, and subsystem hierarchy in a browser, and create various diagrams for each package or subsystem. On each diagram's drawing space, I would create the models shown earlier in this section. Figure 14-18 shows what the hierarchy of the hotel business would look like. I have created four models—Use Case model, Analysis View model, Design View model, and Implementation View model. Each model is a complete representation of the system from a different viewpoint. Within each model, the artifacts are organized by packages or subsystems. Figure 14-18: Overall model, package, and subsystem structure of the hotel example.