Absolute C++ (4th Edition) part 85 pps

7 433 0
Absolute C++ (4th Edition) part 85 pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

848 Patterns and UML Self-Test Exercises The Divide-and-Conquer Sorting pattern must divide the interval being sorted into two smaller intervals. If there were cases in which the split function divided the interval into an empty interval and the rest, then one subinterval would be the same as the original interval being divided, and infinite recursion would result. In the quick-sort realization we avoided this infinite recursion with the following lines from the definition of split: if (up > 0) return (begin + up); else return (begin + 1); //Ensures that both pieces are nonempty. Without this extra adjustment, the function split could compute 0 as the value of up and so divide the interval into two intervals with one of the two being empty. That would produce infi- nite recursion. The way this is usually avoided with a quick-sort realization (and the way that pro- duces the nicest code) is to separate out the split point and divide only the remaining element, so that the array interval is divided into three pieces: the split point, the subinterval before the split point, and the subinterval after the split point. This guarantees that even if one subinterval is empty, the other is shorter than the interval being divided. Thus, infinite recursion is avoided. When these points are taken into consideration, you are likely to change the Sorting pattern to the following when you are designing the quick-sort realization: if ((end - begin) > 1) { int splitPt = split(a, begin, end); sort(a, begin, splitPt - 1); sort(a, splitPt + 1, end); }//else sorting one (or fewer) elements, so do nothing. Patterns are there to help you, not to provide an obstacle. Feel free to adjust them if need be. ■ PATTERN FORMALISM A well-developed body of techniques exists for using patterns. We will not go into the details here. The UML discussed in Section 20.2 is one formalism used to express pat- terns. The place of patterns and any specific formalisms for patterns within the software design process is not yet clear. However, it is clear that basic patterns—as well as certain pattern names, such as Model-View-Controller—have become standard and useful tools for software design. 1. Is a template function definition a pattern? 2. Give the contents of a file named selectionsort.cpp that will realize the selection sort algorithm (see Display 5.8) for the Divide-and-Conquer Sorting pattern given in Display 20.2. (This is the selection sort analog of what was done for the quick sort in Display 20.5.) 20_CH20.fm Page 848 Monday, August 18, 2003 2:08 PM UML 849 3. Which of the following would give the fastest running time when an array is sorted using the quick-sort algorithm: a fully sorted array, an array of random values, or an array sorted from largest to smallest (that is, sorted backwards)? Assume that all arrays are of the same size and have the same base type. UML One picture is worth a thousand words. Chinese proverb People do not think in C++ or in any other programming language. As a result, com- puter scientists have always sought to produce more human-oriented ways of represent- ing programs. One widely used representation is pseudocode, which is a mixture of a programming language such as C++ and a natural language such as English. To think about a programming problem without needing to worry about the syntax details of a language such as C++, you can simply relax the syntax rules and write in pseudocode. Pseudocode has become a standard tool used by programmers, but it is a linear and algebraic representation of programming. Computer scientists have long sought to give software design a graphical representation. To this end, a number of graphical represen- tation systems for program design have been proposed, used, and ultimately found to be wanting. Terms such as flowchart, structure diagram, and many other names of graphical program representations are today only recognized by those of the older gen- eration. Today’s candidate for a graphical representation formalism is the Unified Modeling Language (UML). The UML was designed to reflect and be used with the object-oriented programming philosophy. It is too early to say whether or not the UML will stand the test of time, but it is off to a good start. A number of companies have adopted the UML formalism for use in their software design projects. ■ HISTORY OF UML UML developed along with object-oriented programming. As the OOP philosophy became more and more commonly used, different groups developed their own graphi- cal or other representations for OOP design. In 1996 Grady Booch, Ivar Jacobson, and James Rumbaugh released an early version of UML. The UML was intended to bring together the various different graphical representation methods to produce a standard- ized graphical representation language for object-oriented design and documentation. Since that time the UML has been developed and revised in response to feedback from the OOP community. Today the UML standard is maintained and certified by the Object Management Group (OMG), a nonprofit organization that promotes the use of object-oriented techniques. 20.2 Unified Modeling Language (UML) 20_CH20.fm Page 849 Monday, August 18, 2003 2:08 PM 850 Patterns and UML ■ UML CLASS DIAGRAMS Classes are central to OOP, and the class diagram is the easiest of the UML graphical representations to understand and use. Display 20.6 shows the class diagram for a class to represent a square. The diagram consists of a box divided into three sections. The top section has the class name, Square. The next section has the data specification for the class. In this example there are two pieces of data (two member variables): a value of type double giving the length of a side, and a value topRtCorner giving the location of the top-right corner of the square. (The value topRtCorner is given as a pair of num- bers of type double, which specify a point in x,y-coordinates relative to some origin.) A minus sign indicates a private member. So, for the class Square, all data is private. The third section gives the actions (class member functions). A plus sign indicates a public member. A sharp sign, #, indicates a protected member. So for the class Square, the class diagram shows two public member functions and one protected member func- tion. A class diagram need not give a complete description of the class. When you do not need all the members in a class for the analysis at hand, you do not list all the mem- bers in the class diagram. Missing members are indicated with an ellipsis (three dots). ■ CLASS INTERACTIONS Class diagrams by themselves are of little value, since they simply repeat the class inter- face, possibly with ellipses. To understand a design, you need to indicate how objects of the various classes interact. The UML has various ways to indicate class interactions. Various sorts of annotated arrows indicate the information flow from one class object to another, for example, as in Display 20.1. The UML also has annotations for class groupings into library-like aggregates, for inheritance, and for other interactions. Moreover, the UML is extensible. If what you want and need is not in the UML, you class diagram Display 20.6 A UML Class Diagram +resize(double newSide): void +move(Pair<double, double> point): void #erase( ): void -side: double -topRtCorner: Pair<double, double> Square 20_CH20.fm Page 850 Monday, August 18, 2003 2:08 PM Answers to Self-Test Exercises 851 Self-Test Exercises can add it to the UML. Of course, this all takes place inside a prescribed framework so that different software developers can understand each other’s UML. This is just a hint of what the UML is all about. If you are interested in learning more, consult the references listed at the end of this book. 4. Draw a class diagram for a class whose objects represent circles. Use Display 20.6 as a model. 5. Draw a class diagram for the IntNode class presented in Display 17.4. ■ Patterns are design principles that apply across a variety of software applications. ■ The patterns discussed in this chapter are the Container-Iterator, Adapter, Model- View-Controller, and Divide-and-Conquer Sorting patterns. ■ A pattern can give you a framework for comparing related algorithms for efficiency. ■ The Unified Modeling Language (UML) is a graphical representation language for object-oriented software design. ■ UML is one formalism that can and is used to express patterns. ANSWERS TO SELF-TEST EXERCISES 1. Yes, a template function definition is a pattern, but the term pattern is much more general and encompasses more. Moreover, a useful pattern expressed as a template function would leave some details unimplemented. If the only variation possible is a type parameter, it is still a pat- tern but not likely to be usefully viewed as a pattern. (It can still be useful as a template func- tion, but it might not be useful to view it as a pattern in the sense discussed in this chapter.) 2. //File selectionsort.cpp: the selection sort realization //of the Sorting pattern. #include <algorithm> using std::swap; template <class T> int indexOfSmallest(const T a[], int startIndex, int sentinelIndex) { int min = a[startIndex], indexOfMin = startIndex; for (int index = startIndex + 1; index < sentinelIndex; index++) Chapter Summary 20_CH20.fm Page 851 Monday, August 18, 2003 2:08 PM 852 Patterns and UML if (a[index] < min) { min = a[index]; indexOfMin = index; //min is the smallest of a[startIndex] //through a[index] } return indexOfMin; } template <class T> int split(T a[], int begin, int end) { int index = indexOfSmallest(a, begin, end); swap(a[begin], a[index]); return (begin + 1); } template <class T> void join(T a[], int begin, int splitPt, int end) { //Nothing to do. } 3. An array of random values would have the fastest running time, since it would divide the array segments into approximately equal subarrays most of the time. The other two cases would give approximately the same running time, which would be the worst-case O(N 2 ) running time because the algorithm would always divide an array segment into very unequal pieces, one piece with only one element and one piece with the rest of the ele- ments. It is ironic but true that our version of the quick-sort algorithm has its worst behav- ior on an already sorted array. There are variations on the quick-sort algorithm that perform well on a sorted array. For example, choosing the middle element as the splitting value will give good performance on an already sorted array. But whatever splitting value you choose, there will always be a few cases with this worst-case running time. 4. There is no unique answer, but below is one suitable answer: +resize(double newRadius): void +move(Pair<double, double> point): void #erase( ): void -radius: double -center: Pair<double, double> Circle 20_CH20.fm Page 852 Monday, August 18, 2003 2:08 PM Programming Projects 853 5. PROGRAMMING PROJECTS 1. Recode the quick-sort implementation using the modified pattern given in the program- ming tip section entitled Pragmatics and Patterns. 2. Redo the Sorting pattern using classes. Define a template abstract class called Sort that has a constructor that takes an array argument. That array argument will be the array to be sorted. The class Sort will have member functions named the same and behaving the same as the functions in Display 20.2, except that they will not have an array argument. The array will be a member variable. Define the member function sort following the model of Display 20.2. The functions split and join will be pure virtual functions (Chapter 15). Then define derived classes called Mergesort and Quicksort that realize the Sorting pat- tern using the merge sort and quick-sort algorithms, respectively. The derived classes called Mergesort and Quicksort have definitions for the member functions split and join. Fully test all classes. 3. A vending machine accepts coins whose values sum to the price of a product or whose sum exceeds the purchase price by one coin of any denomination. The vending machine then accepts either a coin release button press that releases the inserted coins (for example, if the customer decides not to buy) or a button press to release the product and any required change, then resets the machine to a “start state.” The vending machine owner can remove money, increase change in storage, or resupply the products on an as-needed basis. Write a design and code the corresponding program that models this situation. 4. In a two-story building a company has one elevator. We want to write a simulator for this elevator so that the building designers can study the elevator system. By each door on each floor there is a button to call the elevator. You decide what (if any) displays should be provided for the user. There are buttons in the car for door open, door close, and an alarm button. You will have to decide what outputs are needed from the sim- ulator so that a user can see and understand what is happening in the simulation. +constructors +getLink( ): IntNode* +getData( ): int +setData(int theData): void +setLink(IntNode* pointer); void -data: int -link: IntNode* IntNode 20_CH20.fm Page 853 Monday, August 18, 2003 2:08 PM 854 Patterns and UML Identify the main objects in this situation. Identify the behavior of each object. Decide how the several objects interact. Then identify the classes and the member functions. Then iden- tify the state that the class(es) must remember to be able to control the elevator. We suggest a clock-driven simulation where everything happens on a clock tick (of say one second, but your program will not have any timing. A click will just be one execution of a loop.) You call a random-number generator to decide how many people arrive on each floor at each tick. Design and code a simulation of the building’s elevator. This is not a hard exercise, but it requires clear thinking. It also requires that you supply some of the details we have left out such as the bell ringing on arrival at a floor, and the door opening, just to mention two things. 5. (Harder version of 4.) Generalize Programming Project 4 to simulate an elevator system where the number of elevators is greater than one and the number of floors is greater than two. In this version each floor will have two call buttons: one to call the elevator to go up and one to call the elevator to go down. For definiteness, use 2 elevators and 10 floors, but the principles will be the same regardless of the number. You have to decide on which of the elevators is called when the call button is pressed under several situations. For example suppose the elevator is called while one elevator is moving toward the caller’s floor while the other is moving away. There are more than 4 such combinations, counting stopped elevators. You will have to decide what additional controls and what display to provide for the users of the elevator. You will have to decide what outputs are needed from the simulator so that a user can see and understand what is happening in the simulation. 20_CH20.fm Page 854 Monday, August 18, 2003 2:08 PM . a programming language such as C++ and a natural language such as English. To think about a programming problem without needing to worry about the syntax details of a language such as C++, you can simply. double -topRtCorner: Pair<double, double> Square 20_CH20.fm Page 850 Monday, August 18, 2003 2:08 PM Answers to Self-Test Exercises 851 Self-Test Exercises can add it to the UML. Of course, this. startIndex + 1; index < sentinelIndex; index++) Chapter Summary 20_CH20.fm Page 851 Monday, August 18, 2003 2:08 PM 852 Patterns and UML if (a[index] < min) { min = a[index]; indexOfMin =

Ngày đăng: 04/07/2014, 05:21

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan