Dr. Dobb's Journal - August 2008 - (Page 47) • Provide the measurement at a location specified by a geographic coordinate. • Provide the measure at a location specified by a great circle coordinate. Now, consider a variety of approaches and refinements to the interface to such a class. The Simplest Case I start with a simple implementation of a PolarArray class that meets the requirements previously specified. I fixed the size of the globe to 8×8 (via const variables); see Listing One. Not a bad start! This simple interface provides the following accessors: • • • • • getValueAtIndex(int) getValueAtGeographicCoordinate(int, int) getValueAtNorthPole() getValueAtSouthPole() getValueAtGreatCircleCoordinate(int, int) Figure 1: Class hierarchy. (North pole) 100 0 1 8 9 16 17 24 25 32 33 40 41 48 49 56 57 (South pole) 200 2 10 18 26 34 42 50 58 3 11 19 27 35 43 51 59 4 12 20 28 36 44 52 60 5 13 21 29 37 45 53 61 6 14 22 30 38 46 54 62 7 15 23 31 39 47 55 63 Clearly, we have satisfied the requirements for this class, and could conceivably halt development on PolarArray at this point. But what kinds of refinement could we make to this class interface? Is there a more intuitive way it could be constructed? In this first implementation, each accessor function actually combines three distinct concepts: • Value lookup. Getting a measurement from the globe. • Coordinate system. Specifying a coordinate system (absolute, geographic, or great circle). • Coordinate. Specifying the domain-specific coordinates themselves (single index, pair of latitude and longitude, or specific pole). The function name specifies the first two concepts (“getValue” indicates we are requesting a value, “at ” denotes which coordinate system), and the function arguments specify the third (the coordinates within the system). Note that getNorthPole() and getSouthPole() actually specify the coordinate itself as part of the function name. While it is not a sin to combine multiple concepts into a single token, it is conceptually clearer if the concepts are differentiated by more than simple capitalization. In the simple aforementioned example, the only delineation is the word “at,” which separates the “getValue” portion of the function name from the coordinate system name. Consider how you might use the various features of object-oriented design to better differentiate the two concepts in play. What if you refactor the index-translation portion of the class so that it is publicly available? You could force users to understand coordinate system and coordinates as distinct concepts from value lookup. Listing Two (available online; see “Resource Center,” page 5) certainly differentiates the value lookup from the coordinate system. It is a bit unwieldy for the client, however, because any request Table 1: Arbitrary measurements on a globe. for a PolarArray’s value at a location must now come in the form of two function invocations instead of one. You have clearly differentiated coordinate system from value lookup, but at the expense of readability. Let’s back up a step and try a different approach. What if you simply factored out the great circle versus geographic system and North versus South Pole distinctions into class arguments? If you add a few enums to the code, the implementation might look like Listing Three (available online). Now we’re getting somewhere! You’ve refactored the distinction between great circle and geographic coordinate systems as a function argument to getValueAtCoordinate( ), as well as North and South Pole coordinates as a function argument to getValueAtPole( ). Let’s take this a step further. What if you used a type-based system to denote the coordinate system rather than a simple enum argument? You will create a Coordinate base class, from which you derive GeographicCoordinate and GreatCircleCoordinate. Similarly, you will create a Pole base class, from which we will derive NorthPole and SouthPole; see Listing Four (available online). Now we’re really making progress! Looking at the example client code, you see that the distinction between the three concepts—value lookup, coordinate system, and coordinate—is clearly differentiated. If you pursue this inheritance-based coordinate specification fully, the class hierarchy looks like Figure 1. By using dynamic_cast to identify the coordinate system, you can finalize the PolarArray code. Pay particular attention to the example client code at the bottom of the listing; notice how it is both readable and clearly differentiates the three concepts into separate tokens; see Listing Five (available online). August 2008 l www.ddj.com l Dr. Dobb’s Journal 47 http://www.ddj.com
Table of Contents Feed for the Digital Edition of Dr. Dobb's Journal - August 2008 Dr. Dobb's Journal - August 2008 Contents Friday Night Fish Fry Alia Vox Developer Diaries Developer’s Notebook A Conversation with Christos Papadimitriou OpenGL and Mobile Devices: Round 2 Ellipse Specification Using Vectors Embed Custom GUIs in WPF Building RIAs on J2EE Foundations Disentangling Concepts in Object-Oriented Systems The Agile Edge Effective Concurrency Swaine’s Flames Dr. Dobb's Journal - August 2008 Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page Cover1) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page Cover2) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 1) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 2) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 3) Dr. Dobb's Journal - August 2008 - Contents (Page 4) Dr. Dobb's Journal - August 2008 - Contents (Page 5) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 6) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 7) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 8) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 9) Dr. Dobb's Journal - August 2008 - Alia Vox (Page 10) Dr. Dobb's Journal - August 2008 - Alia Vox (Page 11) Dr. Dobb's Journal - August 2008 - Developer Diaries (Page 12) Dr. Dobb's Journal - August 2008 - Developer Diaries (Page 13) Dr. Dobb's Journal - August 2008 - Developer’s Notebook (Page 14) Dr. Dobb's Journal - August 2008 - Developer’s Notebook (Page 15) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 16) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 17) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 18) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 19) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 20) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 21) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 22) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 23) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 24) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 25) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 26) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 27) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 28) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 29) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 30) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 31) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 32) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 33) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 34) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 35) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 36) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 37) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 38) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 39) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 40) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 41) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 42) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 43) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 44) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 45) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 46) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 47) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 48) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 49) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 50) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 51) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 52) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 53) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 54) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 55) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page 56) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page Cover3) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.