Chapter 13 – Object-Oriented Design: Use Case Realizations Table of Contents Chapter Overview Learning Objectives Notes on Opening Case and EOC Cases Instructor's Notes (for each section) Key Terms Lecture notes Quick quizzes Classroom Activities Troubleshooting Tips Discussion Questions Chapter Overview This chapter is an extension of Chapter 12 and builds on the concepts presented there. The purpose of this chapter is to provide in-depth knowledge and skills on how to do low-level design of complex systems. The primary focus of this chapter is on developing detailed object-oriented design models, which programmers then use to code the system. The two most important models that must be developed are design class diagrams and interaction diagrams, either communication diagrams or sequence diagrams. Design class diagrams are developed for each layer (domain, view, and data access) of three-layer design to extend the domain model that was developed during analysis. Interaction diagrams extend the system sequence diagrams, also developed during analysis. This chapter also discusses how to associate classes into package diagrams to show relationships and dependencies. Finally, the chapter presents principles of good design as defined by design templates or design patterns. Design patterns is an important topic and a broad area – especially for those that begin their careers as programmers. Most of the development frameworks, e.g. Struts for Java, Zend for PHP, Visual Studio for .NET, are based on the Model-View-Controller (MVC) pattern. Very few Information Systems textbooks even address this subject, yet for programmers working in a team, it is a major component of design and programming discussions. Learning Objectives After reading this chapter, the student should be able to: Explain the different types of objects and layers in a design Develop communication diagrams for use case realization Develop sequence diagrams for use case realization Develop updated design class diagrams Develop multilayer subsystem packages Explain design patterns and recognize various specific patterns Notes on Opening Case and EOC Cases Opening Case New Capital Bank: Part 2: In this case the project leader, Bill Santora, reviews some of the methods that the project team is using to do detailed design. There is also some discussion of the benefits of this approach. Detail design is first done using CRC cards. Then when necessary for the more complex use cases, detailed design is done using sequence diagrams. Also a combined design class diagram was developed that is referenced by all the developers. Some of the benefits are that all programmers are using the same information, the same techniques, and the same approach to programming the system. Hence the system is much more consistent than if each programmer was allowed to program in his own way. A central repository of code enables all programmers to have access to the common pool of code. EOC Cases MoveYourBooksNow.com Book Exchange: MoveYourBooksNow.com is an online clearing house for people to buy and sell books (often textbooks). MoveYourBooksNow maintains no inventory and it acts purely as a clearinghouse for individual buyers and sellers. The case describes the processing requirements. The student is to develop a domain model, a use case diagram, two SSDs, two detailed sequence diagrams, and a design class diagram. Community Board of Realtors (running case): Community Board of Realtors is a professional organization that supports real estate offices and agents. The case for this chapter depends on the descriptions from earlier chapters. The student is to create a first-cut DCD, a first-cut Communication diagram for one use case, a first-cut sequence diagram for a different use case, two multilayer sequence diagrams—one for each use case, and a final DCD. Spring Breaks 'R' Us Travel Services (SBRU) (running case): SBRU is an online travel services that books spring break trips to resorts for college students. The case for this chapter depends on the descriptions from earlier chapters. The student is to create a first-cut DCD, a first-cut Communication diagram for one use case, a first-cut sequence diagram for a different use case, a multilayer sequence diagram with data access classes, a multilayer sequence diagram with view layer classes, a final DCD, and a package diagram. On the Spot Courier Services (running case): On the Spot is a small, but growing, courier service that needs to track customers, package pickups, package deliveries, and delivery routes. This cases extends the solutions developed in Chapter 10. The student is to create a first-cut DCD, a multilayer sequence diagram with data access classes, a multilayer sequence diagram with view layer classes, a final DCD, and a package diagram with dependency relationships. Sandia Medical Devices (running case): Sandia Medical Devices is a company that specializes in medical monitoring through remote, mobile telecommunication devices. This cases extends the solutions developed in Chapter 12. The student is to create a first-cut DCD, a multilayer sequence diagram with data access classes, a multilayer sequence diagram with view layer classes, a final DCD, and a package diagram with dependency relationships. Instructor's Notes Object-Oriented Design with Interaction Diagrams Key Terms use case realization – the process of elaborating the detailed design with interaction diagrams for a particular use case communication diagram – type of interaction diagram that emphasizes the objects that send and receive messages for a specific use case sequence diagram – type of interaction diagram that emphasizes the sequence of messages sent between objects for a specific use case Lecture Notes In Figure 12-1, there are three objects representing the three layers of a system. Each object has certain responsibilities. The input window object has the primary responsibility of formatting and presenting student information on the screen. The student object represents the middle layer, or business logic layer, for the use case. This chapter formalizes the process of precisely identifying methods and defining method signatures, particularly for this layer. The method used to extend the process of detailed design is called use case realization. In use case realization, each use case is taken individually to determine all the classes that collaborate on it. As part of that process, any other utility or support classes are identified. In addition to CRC cards, which were covered in Chapter 12, there are two other models that are useful for systems design—communication diagrams and sequence diagrams. Each type of diagram is capable of providing a rigorous method for use case realization. Interaction diagrams, as the name implies, focus on the interactions between the objects that are required to execute a particular use case. The interactions between the objects are called messages. These methods translate directly to the class methods that support the use case. Use Case Controller The previous chapter briefly introduced the concept of a use case controller in the discussion of CRC cards, but did not elaborate on its use. In reality, a controller class is part of a popular design technique called Model-View-Controller. A use case controller acts as a switchboard, taking input messages and routing them to the correct domain class. In effect, the use case controller acts as an intermediary between the outside world and the internal system. The coupling between the user-interface objects and the problem domain objects is reduced by making a single use case controller object to handle input messages. In this way, domain layer design classes can remain more cohesive by focusing only on the precise functions that truly belong to that domain object. Quick Quiz Q: What are the two types of interaction diagrams? A: Sequence diagrams and communication diagrams. Q: What is the purpose of interaction diagrams? A: To define the messages that are passed between classes to execute a use case. Q: What is a controller class? A: It is a class that acts as the switchboard between the view layer and the business logic layer. Use Case Realization with Communication Diagrams Key Terms none Lecture Notes Understanding Communication Diagrams A communication diagram consists of actors, objects, links, and messages. Figure 13-2 illustrates how these various components are illustrated on the diagram. These components have the following characteristics: Actor. This represents an external role of the person or thing that initiates the use case by sending the initial message, and any other messages that are external to the system. Object. The objects are the instantiated class objects that perform actions to help carry out the use case. In design diagram terms, they receive the messages that request services. Objects can both receive messages and send messages. Link. Links are simply the connectors that illustrate the flow of the messages. They are only used to show where the messages flow. Messages can flow in either direction on a link. Message. Messages are a primary element of the diagram. A message has an originating object or actor, and a destination object or actor. A message is a request for service. A message can also be a return of data from a previous message. A message will invoke a service in an object. The syntax contains of a message has five elements, all of which are optional. The format of a communication diagram message is the following: [true/false condition] sequence-number: return-value: 5 message-name (parameter-list) True/false condition. This is a condition that is tested for true or false. If it is true, then the message is sent; if false, the message is not sent. Sequence number. The sequence number is used to identify the order, or sequence, of the messages. Note that a colon follows the sequence number. Return-value. The return value is a value that the message returns after the completion of the service requested in the forward part of the message. Return values can be returned either with this format (i.e., as part of the message) or as a separate return message. Message-name. This is the name of the message. As noted, it usually uses camel case with the initial letter lowercase. To name the message, it is usually best to describe the service that is requested from the destination object. Parameter-list. The parameter list contains those items that are being passed to the destination object via the message. A major benefit of a communication diagram is that it provides a snapshot view of the classes and messages. However, a disadvantage is that there is not much space allowed for messages, so it can easily become cluttered with overlapping information. Figure 13-3 is a communication diagram for the Create customer account use case. Object-Oriented Design with Communication Diagrams We will learn how to do “use case realization” using this communication diagrams by working through the same use case shown in figure 13-3, Create customer account. Input Models. Figure 13-4 shows a first-cut design class diagram with navigation arrows. The selection of which classes to include is purely an estimate at this point. The other source of input information comes from the analysis models. Chapter 5 developed several models for this use case, including a use case description (Figure 5-2), an activity diagram (Figure 5-4), and a system sequence diagram (Figure 5-10). Figure 13-5 is a duplicate of the system sequence diagram. Extend Input Messages. For each input message, extend the message to the internal objects within the :System object. Follow this process: From the first-cut design class diagram, identify the classes that will be required to carry out the execution of the message. Place the corresponding objects on the diagram. Beginning with the first input message, identify each message that will be required for each of the included objects on the diagram. For each message, ensure that the origin object has navigation visibility to the destination object. Determine which object should have primary responsibility for completing the required service. Place appropriate messages based on navigation and responsibility. Name each message to reflect the service requested from the destination object. Identify and include the parameters that the destination object will require to carry out the requested service. Identify and name any return messages or return values that need to be returned to origin objects. Looking at the first input message, createNewCustomer (name, phones, emails), we decide the following, as shown in Figure 13-6. The required classes for this message are CustomerHandler and Customer. The required message is createNewCustomer and comes from the Clerk to the :CustomerHandler. The :CustomerHandler then forwards that same message to the :Customer object. The :Customer object is the appropriate object to carry out this service. The constructor method in the Customer class instantiates a new :Customer object. This is shown in the diagram with a message directly to the :Customer object. The name of the message is appropriate as given in the SSD. The parameters on the SSD, however, do not reflect the attributes of the Customer class. The accountNo and status attributes are both determined by the constructor. The other attributes—name, mobilePhone, homePhone, and emailAddress—need to be passed in as arguments. The input parameter list will be modified to reflect these changes. Do the same for the other messages, enterAddress (address) and enterCreditCard (cc-info). Figure 13-9 is the final communication diagram. Final Design Class Diagram. Figure 13-10 illustrates the final design class diagram. In this instance the constructor methods for each class are included. Quick Quiz Q: What are the three steps to extending input messages? A: 1. Identify the objects, 2. Identify the message for each object, 3. Describe each message with name, parameters, etc. Q: How does a communication diagram show sequence of steps? A: With sequential numbering. Q: What do the link lines indicate? A: The link lines are used to show the transmittal of messages between objects. Q: What is the advantage of a communication diagram over a sequence diagram? A: A communication diagram focuses more on the objects and gives a better overview of the use case. Use Case Realization with Sequence Diagrams Key Terms activation lifeline – a representation of the period during which a method of an object is alive and executing Lecture Notes In this section we first explain how to read and understand a sequence diagram. Then we explain the design process, after which we go through some detailed examples. Understanding Sequence Diagrams The most important information on an SSD is the sequence of messages between the actor and the system. There may be a single input message or many. The input messages may have data parameters or not. Figure 13-11 is a sample sequence diagram. In many ways, it is similar to a communication diagram. The boxes are instantiated objects from the corresponding classes. Object notation is used. Some objects are named objects, such as a C:Customer. The primary benefit of the sequence diagram is the ability to lay out the messages from top to bottom to emphasize the sequence of firing. Below each actor and object is a lifeline, which is used as an indicator of the life of the object. Messages are attached to the lifeline either as a source point or a destination point. Attached to locations of each lifeline are vertical boxes representing activation lifelines. You might consider these activation lifelines the time period when a method is executing. When a message is sent from an originating object to a destination object, in programming terms, it means that the originating object is invoking a method on the destination object. Thus, by defining the messages to various internal objects, we are actually identifying the methods of that object. Design Process for Use Case Realization The design process for using sequence diagrams is the same as it is for communication diagrams. The starting point for the detailed design of a use case is always its SSD and the first-cut design class diagram. Other models, such as a use case description and activity diagram, are also helpful. Figure 13-11 is the sequence diagram solution of the Create customer account use case. It was developed using the same three steps that were used to extend communication diagram messages. It has the same set of messages, but displayed differently. Sequence Diagram: Fill shopping cart Use Case The process is the same as before. This use case is a just a different type of example. Figure 13-12 shows the activity diagram for this use case. This use case “included” three other use cases. By designing the use case in this manner, with other use cases included, our solution will only have to focus on those functions that actually add items to the shopping cart. Figure 13-13 shows that there are only two input messages to the system: adding an item and adding an accessory item. As you analyze the SSD, notice that adding an item to the shopping cart and adding an accessory to the cart are the same operation. We begin this design by developing the first-cut DCD. The Customer, Cart, and CartItem classes are necessary because the use case will be adding items for this customer to the customer’s cart. To create a cart item, the system will need to know what product it is, if there are items in stock, and the price for the item. Therefore, other classes that are required are InventoryItem, ProductItem, and PromoOffering. As we develop the solution, we may have to add classes. Navigation visibility between these classes will be from the controller to the Customer class and to the Cart class once it has been created. The Cart class will be able to access the CartItem class. The CartItem class should have visibility to the other classes, such as ProductItem and InventoryItem, that contain the necessary information. Figure 13-14 shows the DCD. Figure 13-15 shows this first step. The :CartHandler checks to see if it is the first item, and if so, sends a createCart message to :Customer. Notice the true/false condition on that message. The :Customer object sends a create message directly to :OnlineCart to instantiate a new cart. A reference to the new cart is returned first to :Customer, which then forwards it on to :CartHandler. Now both have navigation visibility to the newly created online cart. Because :CartHandler now has visibility to :OnlineCart, it sends a message directly to the cart to addthe appropriate item. :OnlineCart creates a new cart item and passes the data to :CartItem to instantiate a new cart item. :CartItem retrieves the necessary data to complete its attributes. Figure 13-16 illustrates this next set of messages. Referring back to Figure 13-13, note that there is another input message, addAccessoryToCart (…), with the same input parameters. Hence, the same set of internal messages are required. The only difference is that adding accessories is an optional activity. Figure 13-17 is the full use case with both sets of messages shown, one set for an item and a repeating set for the accessories. Important considerations include: Which classes “own” other classes and hence have responsibility to create them? Which objects are the sources and which are the destinations for the messages? Which classes have visibility to which other classes? And how is that visibility supported? Guidelines and Assumptions for Sequence Diagram Development Guidelines: The following three design tasks are done to produce the preliminary sequence diagram: Take each input message and determine all of the internal messages that result from that input. For that message, determine its objective. Determine what information is needed, what class needs it—the destination—and what class provides it—the source. Determine whether any objects are created as a result of the input As you work with each input message, identity the complete set of classes that will be affected by that message. Select all the objects from the domain class diagrams and include use case preconditions and postconditions. Flesh out the components for each message by adding iteration, true/false conditions, return values, and passed parameters. Assumptions: The development of the first-cut sequence diagram is based on several simplifying assumptions. The following are three of these assumptions: Perfect technology assumption. We first encountered this assumption in Chapter 5 when we were identifying business events. We continue that assumption here. We do not include steps such as the user having to log on or testing the availability of the network. Perfect memory assumption. You may have noticed that we just assumed that the necessary objects were in memory and available for the use case. We did not ask whether those objects were created in memory. We will change this assumption when we get to multilayer design. In multiple-layer design, we do include the steps necessary to create objects in memory. Perfect solution assumption. The first-cut sequence diagram assumes that there are no exception conditions. No logic is included to handle a situation in which the requested catalog or product is not found. Developing a Multilayer Design So far in the development of the sequence diagram, we have focused only on the classes in the problem domain layer. In many instances, this may be sufficient documentation to program the solution—either by yourself or with another programmer. Once you have a solid design for the problem domain classes, adding the view layer and the data access layer is a straightforward, if time-consuming, process. Every system will need view layer classes to represent the input and output screens for the application. Data access layer classes aren’t always required. The data access layer is required when the business logic is fairly complex and should be isolated from the SQL statements that access the database. Designing the View Layer One advantage of adding the view layer to the sequence diagram is that the programmer can see how the view layer classes integrate with the rest of the design. It becomes a check to make sure the design is correct and complete. It is a good practice to verify several use cases to ensure that the developers understand how the view layer represents the user-interface design and how all the elements integrate together for a smooth program execution. Thus, input for view layer design includes the use case description, the SSD, the activity diagrams, the first-cut design class diagram, and, finally, the user-interface layouts or mock-ups. We return to the Add customer account use case and add the view layer. Remember from the discussion of communication diagrams that there are three input messages: createNewCustomer, enterAddress, and enterAccount. The starting point is Figure 13-11, which is the sequence diagram with the problem domain classes. The process to add the view layer is simply to add an object for each input form or screen. First add the appropriate messages from the Clerk to the input «view» objects. In this instance, the messages are the ones identified from the SSD, and which were used in Figure 13-11. Figure 13-18 illustrates the resulting diagram with both the domain and view layers. If we look at the other use case we have been using, Fill shopping cart, we have a more complex example. Remember that the Fill shopping cart use case included other use cases for Search for item and View accessory combinations. Obviously, all those use cases go together for a rich and efficient user experience. In Figure 13-19, we have added the two view layer objects for searching items and viewing accessories. Adding the view layer to your design is a good way to verify that the user interface that was developed with the users is consistent with the application design. All the input messages that were identified and documented on SSDs must be handled by the user interface. Designing the Data Access Layer In most cases, problem domain classes are also persistent classes, which means that their data values must be stored by the system even when the application isn’t executing. The whole purpose of a relational database is to provide this ability to make problem domain objects persistent. One of the problems with object-oriented programs that use relational databases is that there is a slight mismatch between programming languages and database SQL statements. For example, in a database, tables are linked through the use of foreign keys (see Figure 9-9), such as a cart having a CustomerID as a column so the order can be joined with the customer in a relational join. However, in object-oriented programming languages, the navigation is often in the opposite direction (i.e., the Customer class may have an array of references that point to the OnlineCart objects. In other words, design classes don’t have foreign keys. This chapter takes a somewhat simplified design approach in order to teach the basic ideas without getting embroiled in the complexities of database access. When a new persistent object is created in memory, the constructor method often initiates the process to write it to the database. When an object is updated, it also needs to be written to the database. The common method to do that is simply to send a message to the data access object. Either the set of object attributes can be sent as parameters or simply as a reference to the object itself. The data access method can pull out the attributes, format an SQL insert or update statement, and write it to the database. Figure 13-20 is an enhancement of Figure 13-18 with the data access layer added. When the database needs to be read to retrieve data, usually as part of a constructor, it is a little more complex. There are two common techniques. One technique is to have the constructor method of an object read the database and obtain the required data to flesh out its attributes and create an object in memory. Figure 13-21 illustrates this technique. Another technique is to send a message to the data access layer object and have it read the database and then instantiate a new problem domain object. This second technique is better when a set of objects needs to be created from a database access that returns an unknown number of rows. Figure 13-22 illustrates this second technique. The Data Access Layer for the Fill Shopping Cart Use Case: Figure 13-23 is a portion of the Fill shopping cart use case from Figure 13-16. In this diagram, we have only included the AddItem message to limit the complexity of the drawing. As you look closely at Figure 13-23, note that every object that sends a message to another object must have navigation visibility to that object. We review the messages requiring data access. [first Time]createCart—The cart handler is going to send a message to a customer object to create a cart. First, it needs to ensure that there is a customer object in memory. It sends a findCustomer message to the aC:Customer object to find and create itself from the database. It does so by sending a message to the :CustomerDA object to read the database and return the appropriate customer object. addItem—This message is initially the same in both figures. After aCrt:CartItem has been created and populated with data, a message is sent to the data access object to save the data to the database. getPrice, getDesc, updateQty—These three messages all access or update the database. Therefore, each also requires a previous message to find the appropriate data from the database, which is stored in a domain object in memory. Quick Quiz Q: What is the difference between an SSD and a sequence diagram? A: The SSD only has a single processing object :System. A sequence diagram includes all the internal objects and messages. Q: How can return values be shown for messages? A: Two ways. Either as a return value on the message, or as a return dashed line. Q: What are the parts of a message syntax and what do they mean? (review SSDs) A: * means repeated message, [true/false condition] indicates if message can “fire” or not, return-value is the data returned from the message, := equals equals, message-name is a descriptor of the service requested by the message, (parameter-list) is the input data sent to the destination object. Q: What does the activation life line mean? A: It is the duration that the object is alive and processing a given received message. Q: What is the first step in creating a use case design? A: Create the first-cut design class diagram. Q: Why is that important? A: To know which classes must be included in the sequence diagram and to identify what navigation visibility to assign. Q: What things are added to the DCD after a sequence diagram is complete? A: Method names, additional navigation visibility and any new classes that were needed. Updating and Packaging the Design Classes Key Terms dependency relationship – a relationship between packages, classes, or use cases in which a change in the independent item requires a change in the dependent item Lecture Notes Design class diagrams can now be developed for each layer. In the view layer and the data access layer, several new classes must be specified. The domain layer also has some new classes added for the use case controllers. The first step in updating the DCD is to add the method signatures based on the information from the sequence diagrams. Three types of methods are found in most classes: (1) constructor methods, (2) data-get and data-set methods, and (3) use case-specific methods. To avoid information overload, most developers don’t include the get and set methods in the DCD. The process of adding method signatures to a design class is to go through every sequence diagram and find the messages sent to that class. Each message indicates a method. In addition to the method signatures, the DCD is updated with any new classes and any new navigation arrows. Structuring the Major Components with Package Diagrams As you learned previously, a package diagram in UML is simply a high-level diagram that allows designers to associate classes of related groups. In this example in Figure 13-25 the classes are placed inside the appropriate package based on the layer to which they belong. The other symbol used on a package diagram is a dashed arrow, which represents a dependency relationship. The arrow’s tail is connected to the package that is dependent, and the arrowhead is connected to the independent package. A good way to think about a dependency relationship is that if one element changes (the independent element), the other (dependent) element might also have to be changed. Dependency relationships are used in package diagrams, class diagrams, and even interaction diagrams. Package diagrams can also be nested to show different levels of packages. Implementation Issues for Three-Layer Design Using design class diagrams, interaction diagrams, and package diagrams, programmers can begin to build the components of a system. Based on the design principle “object responsibility,” it is possible to define which program responsibilities belong to each layer. If you follow these guidelines when writing code, a system will be much easier to maintain throughout its lifetime. Let us summarize the primary responsibilities of each layer. View layer classes should have programming logic to perform the following: Display electronic forms and reports. Capture such input events as clicks, rollovers, and key entries. Display data fields. Accept input data. Edit and validate input data. Forward input data to the domain layer classes. Start and shut down the system. Domain layer classes should have responsibilities to perform the following: Create problem domain (persistent) classes. Process all business rules with appropriate logic. Prepare persistent classes for storage to the database. Data access layer classes should have responsibilities to perform the following: Establish and maintain connections to the database. Contain all SQL statements. Process result sets (the results of SQL executions) into appropriate domain objects. Disconnect gracefully from the database. Quick Quiz Q: What is the purpose of package diagrams? A: To show logical relationships between sets of classes. Q: What is a dependency arrow? Which way does it point? A: A dependency arrow shows that one class (or package) is dependent on another, and if there are changes in the independent item, there will most likely be changes in the dependent item. It points from the dependent item to the independent item. Q: What are the three main responsibilities of the domain layer classes? A: To create problem domain classes, to process business logic, and to flesh out persistent classes so that they are prepared for data storage. Design Patterns Key Terms design patterns – standard design techniques and templates that are widely recognized as good practice Lecture Notes Standard design templates have become popular among software developers because they can speed object-oriented design work. The formal name for these templates is design patterns. Systems that are based on good design principles aren’t only easier to develop and put into operation the first time, they are also much easier to maintain. Such concepts as object responsibility, coupling, cohesion, protection from variations, and indirection are key design principles that are implemented through the use of design patterns. In this section we introduce only a few design patterns to teach the concept. There are many more design patterns. Use Case Controller In Chapter 12, you were introduced to the concept of a use case controller and Model-View-Controller. For any particular use case, messages come from the external actor to a windows class (that is, an electronic input form) and then to a problem domain class. Designers often define intermediary classes that act as buffers between the user interface and the domain classes. Figure 13-26 provides a more formal specification for the use case controller pattern. Note that this specification has five main elements: Pattern name Problem that requires a solution Solution to or explanation of the pattern Example of the pattern Benefits and consequences of the pattern A use case controller acts as a switchboard, taking input messages and routing them to the correct domain class. A use case controller also contains logic that controls the flow of execution for the use case. In the examples that follow, we define a controller class for each use case. Adapter The adapter pattern is also a good example of the design principles “protection from variations” and “indirection.” The adapter design pattern works just like the electrical adapter; it plugs an external class into an existing system. The method signatures on the external class are different from the method names being called from within the system, so the adapter class is inserted to convert the method calls from within the system to the method names in the external class. It is a powerful and elegant solution to making a system more maintainable. Experienced developers use this pattern frequently—for foreign classes and for internally written classes that may need frequent upgrades. Figure 13-28 describes the Adapter pattern. Factory In the discussions of detailed design, we have often expressed the need to have utility classes. What class should create these utility objects? In most situations, it doesn’t make sense for domain classes to create them because it isn’t a listed responsibility of domain classes. A popular solution in object-oriented programming is to have some classes that are factories. In other words, these classes instantiate objects of the utility classes. Figure 13-29 is an example of a factory class. Singleton Some classes must have exactly one instance—for example, a factory class or the main window class. Because these classes are instantiated from only one place, it is easy to limit the logic to create only one object. Other classes must have exactly one instance but can’t be easily controlled by having only one place to invoke the constructor. Depending on the system’s flow of logic, a particular class might get instantiated from multiple locations. However, only one instance needs to be created, so the first one that needs it creates it, and every other class uses the one that was initially created. This common problem has a standard solution: the singleton pattern. The singleton pattern has the same basic logic as the factory method pattern. The difference is that the singleton class has code that applies to itself as static methods. Figure 13-30 presents the template for the Singleton class. Quick Quiz Q: What is the purpose of the Controller class? A: The Controller acts as a switch board between the view layer and the business logic layer. It reduces the coupling between these two layers. Q: What design principles are implemented by the Adapter pattern? A: Protection from variations, and indirection. Q: What design principle is implemented by the Singleton pattern? A: Object responsibility Q: What is the difference between the factory and the singleton? A: The factory creates objects of other classes, the singleton creates an object of itself. Classroom Activities The two big topics for this chapter are designing with interaction diagrams, including communication diagrams and sequence diagrams, and design patterns. Use case design is a skill that is best learned by doing. For this chapter the best classroom activity is practicing developing sequence diagrams. Effective classroom activities include doing some of the homework problems or end-of-chapter cases in class. First assign a use case to student teams or pairs and then review the solutions in class. It is important for the teacher to have and present a correct solution. In teaching this material, the teacher should actually do the design, step-by-step, with the students. The students need to see the thought process of thinking through the design of the messages and message labels. Design pattern activities could include some reverse engineering of existing systems. Many existing system have examples of controller classes, factory classes, and singleton classes. Other activities could be a review of other widely used design patterns. Troubleshooting Tips Systems design with sequence diagrams is a complex process. Students will need to practice it multiple times before they feel comfortable with the process. To teach these concepts we have summarized the design process in this section, along with a set of questions that are helpful in the design process. You may need to spend considerable class time teaching design principles to students. You can find additional information about these principles in Craig Larman’s book, Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process, Second Edition (see the chapter on GRASP design patterns). You can also refer to the text, Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development, Third Edition. Design Summary Object responsibility is the foundation upon which all object-oriented methodology is based. Design is use-case driven. The use case controller class provides a common access point into the system logic for a given use case or business transaction. As indicated in the chapter, the first step in this activity is to identify the core process required for the use case. By core, we mean only the classes from the domain model. If we identify this core process correctly, the rest of the design will evolve easily. This design activity consists of three steps, each of which corresponds to a layer in three-layer design. First, design the core process based on the domain model. Second, add the data access layer classes. Third, add the view layer classes (that is, the GUI). The basic principle of design is to identify both the classes that are involved in the use case and the messages that must be passed between the objects to execute the use case. The system sequence diagram, in conjunction with the activity diagrams or fully developed use case workflow descriptions, drives this design process. The system must process each input message from the actor to the system. Design involves defining of all the internal tasks that the system must perform to process an input message. For example, if the input message is a “verify” or “find” type of message, the system must find the right object and verify its existence or status or attribute values. The designer must identify all the objects that are associated with the task and each object’s responsibility. This is the central activity of doing object-oriented design. Students need to practice this activity quite a bit to completely understand how it works. If you are new to object-oriented design, you will probably need to supplement the material in the textbook with other readings. Again, we recommend Craig Larman’s book (2nd edition or 3rd edition) as a fairly easy to read that can presented in small chunks. The following questions can help students develop a correct and comprehensive set of internal messages for each input message: What class has the primary responsibility to “receive and control the processes” for the input message? (Usually, this is the use case controller class.) What domain model class should take primary responsibility for the “core” processes of the service requested by this input message? What information is required? What comes in on the input message? What information is required to carry out the service request? From where does this information come (for example, which objects)? What objects need to be instantiated? What class has the responsibility to instantiate those objects? What relationships need to be built? What messages may be needed to establish these relationships? What information needs to be verified and checked? What other objects need to be involved to provide this verification? What information needs to be returned? What outputs are expected from the input message? What navigation visibility is available (from the first-cut design class diagram)? What other visibility will be required (and, therefore, built as part of the process)? Is the solution consistent with low coupling and high cohesion? Is it consistent with principles of good object responsibility? Is the solution complete—this is, does it satisfy the post-conditions described in the use case specifications? Discussion Questions Although most of the class time should be utilized working through examples, there are a few questions that you may find interesting to discuss. 1. Communication Diagrams and Sequence Diagrams Communication diagrams and sequence diagrams are both interaction diagrams. Do they capture the same information? Which model should be used for design and why? Are there instances in which both communication diagrams and sequence diagrams should be used? What should be the standard for developers in a typical organization? Communication diagrams and sequence diagrams are both types of interaction diagrams used in software design to visualize the interactions between objects or components within a system. While they serve similar purposes, they have differences in their representations and usage: 1. Capturing Information: • Communication Diagrams: These diagrams focus on illustrating the relationships between objects or components in a system. They emphasize the flow of messages or interactions between objects over time. • Sequence Diagrams: Sequence diagrams, on the other hand, depict the interactions between objects in a chronological sequence. They emphasize the order and timing of messages exchanged between objects during a particular scenario or use case. 2. Design Usage: • Communication Diagrams: Communication diagrams are often used to provide an overview of the relationships between objects in a system. They are particularly useful for understanding the structural organization of objects and their interactions in a more abstract manner. • Sequence Diagrams: Sequence diagrams are typically used to model the dynamic behavior of objects over time. They are well-suited for detailing the specific sequence of interactions between objects in a particular scenario or use case. 3. Usage Together: • There are instances where both communication diagrams and sequence diagrams can be beneficial. For example: • Initial Design: Communication diagrams can be used initially to establish the structural relationships between objects. Once the high-level structure is defined, sequence diagrams can then be used to delve deeper into the detailed interactions within specific scenarios. • Complex Systems: In complex systems, using both types of diagrams can provide a comprehensive understanding of both the structural relationships and the dynamic behavior of objects. 4. Standard for Developers: • In a typical organization, the choice between communication diagrams and sequence diagrams may depend on the stage of development, the complexity of the system, and the preferences of the development team. • It's common for developers to use sequence diagrams to model specific scenarios or use cases during the detailed design phase when they need to understand the precise sequence of interactions between objects. • However, communication diagrams can still be valuable for providing a higher-level overview of object relationships, especially during the early stages of design or when focusing on system architecture. Ultimately, the selection of the appropriate diagram depends on the specific requirements of the project, the level of detail needed, and the preferences of the development team. Both communication diagrams and sequence diagrams serve important roles in software design and can complement each other in providing a holistic view of the system's interactions. 2. Sequence Diagrams Sequence diagrams can get very large and messy. What can be done to make them easier to use with? Is it necessary to do a complete three-layer design for every use case? Would you recommend keeping sequence diagrams up to date after the system is developed? Why or why not? Do you think that today's developers actually use sequence diagrams? If so, how would you think they may be used? Sequence diagrams can indeed become cumbersome and difficult to navigate, especially for complex systems. To make them more manageable, several strategies can be employed: 1. Abstraction: Break down large sequence diagrams into smaller, more focused ones that represent specific interactions or subsystems within the system. This helps to maintain clarity and avoid overwhelming the viewer with unnecessary detail. 2. Use of Layers: While a complete three-layer design might not be necessary for every use case, adopting a layered approach can help organize the sequence diagrams and provide a clearer understanding of the system's architecture and interactions. 3. Documentation: It's essential to keep sequence diagrams updated during the development process to reflect any changes or updates made to the system. This ensures that the documentation remains an accurate representation of the system's behavior and facilitates easier maintenance and future development. 4. Tooling and Visualization: Utilize tools that support interactive visualization and exploration of sequence diagrams. These tools often provide features such as zooming, filtering, and collapsing/expanding sections, making it easier to navigate and understand large diagrams. 5. Collaboration: Foster collaboration among team members to review and refine sequence diagrams regularly. This helps ensure that the diagrams accurately reflect the system's behavior and promote a shared understanding among team members. As for whether today's developers use sequence diagrams, it depends on various factors such as the development methodology, team preferences, and the complexity of the system being developed. While some developers may rely heavily on sequence diagrams for design and documentation purposes, others may prefer alternative approaches such as UML class diagrams, flowcharts, or even informal sketches. If developers do use sequence diagrams, they may employ them in several ways: 1. Design: Sequence diagrams can be used during the design phase to visualize the interactions between different components or modules within the system, helping developers identify potential issues or design flaws early on. 2. Communication: Sequence diagrams serve as a visual aid for communication among team members, stakeholders, and clients, facilitating discussions about system behavior and requirements. 3. Testing: Sequence diagrams can be used to generate test cases and scenarios, ensuring comprehensive test coverage of the system's functionality. 4. Debugging: During the development and debugging process, sequence diagrams can help developers trace the flow of control and data through the system, aiding in identifying and resolving bugs or performance issues. In conclusion, while sequence diagrams can be challenging to manage, they remain a valuable tool for designing, documenting, and understanding system behavior, especially in the context of complex software development projects. Keeping them updated and utilizing appropriate strategies can enhance their usability and effectiveness in modern development practices. 3. Design Patterns How widely used are design patterns in today's development environments? There are lots of programmers in the world today that are self-taught. Do you think they have learned about design patterns? Do you think they are better or worse from not having a formal programming education? Design patterns continue to be widely used in today's development environments, across a variety of programming languages and domains. They offer proven solutions to common design problems, promoting maintainability, scalability, and code reusability. Many software engineering teams incorporate design patterns into their development practices, either implicitly through experience or explicitly through design reviews and guidelines. Regarding self-taught programmers, their exposure to design patterns can vary significantly. While some may have learned about design patterns through online resources, books, or community forums, others might not be familiar with them at all. Self-taught programmers often rely on practical experience, experimentation, and problem-solving skills to develop their coding abilities. Whether self-taught programmers are better or worse off without formal programming education depends on various factors: 1. Adaptability: Self-taught programmers often exhibit strong adaptability and resilience, as they've learned to navigate complex programming concepts independently. They might excel in hands-on problem-solving and practical application of programming skills. 2. Knowledge Gaps: However, self-taught programmers may have gaps in their knowledge, particularly in foundational computer science principles, software engineering best practices, and design patterns. Without formal education, they might miss out on structured learning opportunities and theoretical underpinnings that can deepen their understanding of programming concepts. 3. Industry Demand: In today's technology-driven world, employers often prioritize practical skills and experience over formal education. Self-taught programmers who can demonstrate proficiency in programming languages, frameworks, and development tools may find ample opportunities in the job market. 4. Continuous Learning: Regardless of educational background, continuous learning is essential for staying relevant in the ever-evolving field of software development. Self-taught programmers can bridge knowledge gaps by actively seeking out resources, participating in online courses, attending workshops, and collaborating with peers. 5. Team Dynamics: In professional settings, self-taught programmers may benefit from working in diverse teams where they can learn from colleagues with formal education and industry experience. Collaborative environments foster knowledge sharing, mentorship, and professional growth. In conclusion, while formal programming education provides a structured foundation and exposure to essential concepts such as design patterns, self-taught programmers can still thrive in the industry through practical experience, continuous learning, and adaptability. Whether they are better or worse off depends on individual circumstances, commitment to learning, and the ability to leverage available resources to enhance their skills. 4. Modeling One of the questions that students often ask is about the need and utility of doing detailed design. What not just do the design while you are programming? So questions such as: Is there a benefit of doing design using sequence diagrams? When is it advantageous to use sequence diagrams? When would it be better just to do design at the same time you write the code? Should sequence diagrams be kept after The question of whether to perform detailed design before programming or to design concurrently while writing code is a common dilemma in software development. While both approaches have their merits, there are situations where each is advantageous. Let's explore the benefits of using sequence diagrams for design and when it might be advantageous to do so: Benefits of Using Sequence Diagrams for Design: 1. Visualization: Sequence diagrams provide a visual representation of how different components or objects interact with each other during the execution of a particular use case or scenario. This visualization helps developers better understand the flow of control and data within the system. 2. Communication: Sequence diagrams serve as a communication tool among team members, stakeholders, and clients, facilitating discussions about system behavior, requirements, and potential edge cases. They provide a common language for expressing complex interactions in a clear and concise manner. 3. Early Detection of Design Flaws: By creating sequence diagrams during the design phase, developers can identify potential design flaws, dependencies, and bottlenecks before writing code. This proactive approach helps mitigate risks and ensures that the final implementation aligns with the intended system architecture. 4. Documentation: Sequence diagrams serve as documentation for the system's behavior, providing a reference for future development, maintenance, and debugging efforts. Keeping sequence diagrams updated throughout the development process ensures that the documentation remains accurate and reflects any changes made to the system. Advantages of Designing Concurrently with Coding: 1. Agility: Designing concurrently with coding allows for a more agile development process, where developers can quickly iterate on designs, implement features, and gather feedback from users. This iterative approach fosters rapid prototyping and adaptation to changing requirements. 2. Tight Feedback Loop: By immediately translating design decisions into code, developers can receive immediate feedback on the feasibility and effectiveness of their designs. This tight feedback loop promotes collaboration, problem-solving, and continuous improvement throughout the development cycle. 3. Complexity Management: For small, straightforward features or projects, designing concurrently with coding may be sufficient to manage complexity effectively. In such cases, the overhead of creating and maintaining separate design artifacts like sequence diagrams may be unnecessary. Conclusion: In conclusion, the decision to use sequence diagrams for design depends on the specific needs and constraints of the project. While sequence diagrams offer benefits such as visualization, communication, and early detection of design flaws, there are situations where designing concurrently with coding may be more advantageous, particularly for agile development environments or small, straightforward projects. Ultimately, the key is to strike a balance between upfront design and iterative development practices, adapting the approach based on the project's complexity, requirements, and team dynamics. Regardless of the chosen approach, keeping sequence diagrams updated and aligned with the evolving system architecture can provide valuable documentation and insights for future development efforts. Instructor Manual for Systems Analysis and Design in a Changing World John W. Satzinger, Robert B. Jackson, Stephen D. Burd 9781305117204, 9781111951641
Close