Chapter 4. Introducing the Mapplet Project

Introducing the Mapplet Project

It's more difficult (and more time consuming) to base a book around a real software project than it is to write one with a toy example. For this book, though, we thought it was important to show how DDT works on the real thing, as we expect a bit of skepticism from test-driven developers. This chapter introduces you to our example project, which we call the Mapplet 2.0, and Chapters 58 will show how we've unit tested it (at two levels of abstraction) and how we've done acceptance testing against use-case scenarios and against the requirements. As you can see in the chapter-opener diagram, these two levels of developer testing and two levels of independent QA testing form the core of DDT.

The Mapplet project itself is a next-generation version of the map-based hotel finder that we presented in Agile Development with ICONIX Process. That book was an experiment in minimalist modeling—we were pushing the boundaries of how little modeling we could get away with and still come up with an application that satisfied the use cases and met the requirements. In this book, we employed the full arsenal of ICONIX Process techniques, augmented with their design-driven testing counterparts. This book focuses on testing and leaves out most of the design process; however, we're documenting the forward-thinking design process in a companion book from ESRI Press called Best Practices for ArcGIS Server Development.

As for the Mapplet project itself, we wanted Mapplet version 2 to work "more or less like Mapplet 1" (i.e., show me a map with hotels on it), with a few notable extensions, including the following:

  • Worldwide coverage (Mapplet 1 was restricted to the US)

  • A better, more modern user interface (we decided to use Flex)

  • Real-time rate and availability checking (using an XML interface to the hotel database)

  • Integration with a "photography overlay" (and an ability to see satellite imagery of a destination)

We think that, in addition to providing a good example for a couple of book projects, we've actually managed to break some new ground in the travel industry in terms of improving the "hotel shopping experience" for travelers, and we invite you to try out the Mapplet on www.vresorts.com.

We'll present the Mapplet 2.0 architecture and design in this chapter, which will serve to establish context for the testing chapters that follow. We'll focus on two use cases: Quick Search(which shows all the hotels in a particular area of interest) and Advanced Search(which lets you quickly zero-in on exactly the sort of hotel you're looking for, and makes sure it's available on your travel dates).

Top Ten ICONIX Process/DDT Best Practices

When embarking on a new project, or maintaining an ongoing project through successive iterations, be sure to follow our top-ten "to-do" list. We divide our list into two categories.

First, we begin with "starting the project right."

  • 10. Create an architecture.

  • 9. Agree on the business requirements, and test against them.

  • 8. Drive your design from the problem domain.

  • 7. Write use cases against UI storyboards.

  • 6. Write scenario tests to verify that the use cases work.

  • 5. Create conceptual and detailed designs, and test against them.

Then we move on to "keeping the project on track."

  • 4. Update the model regularly to keep it in-sync with the code.

  • 3. Keep the acceptance test scripts in-sync with the requirements.

  • 2. Keep the automated tests up-to-date.

  • 1. Compare the release candidate with the original use cases.

As you can see, this list forms something of a high-level roadmap of "best practices" for your software project. Steps 5, 6 and 9 are the main focus of Part 2, so we won't cover them in this chapter. The remaining steps (which aren't specifically to do with testing) are discussed in this chapter, using the Mapplet project as the example. We cover these remaining steps in more detail in the book's companion volume, Use Case Driven Object Modeling with UML: Theory and Practice. If you're interested in the forward-looking design of the Mapplet, you might also like to check out our upcoming book, Best Practices for ArcGIS Server Development, from ESRI Press.

Note

ICONIX Process can be thought of as a fusion between rapid application development (RAD) (because the code is driven from the storyboarded UI prototypes, which are put together directly in Flash Builder, Visual Studio, etc.), domain-driven design (because the entity classes are driven directly from the domain model, keeping the developers from going down the path of creating one big MXML file with at least 50,000 functions in it), use-case-driven development (because the use cases hold it all together and keep development focused on the customer's requirements), and responsibility-driven design (allocating behavior to classes using sequence diagrams).

10. Create an Architecture

The architecture represents a high-level overview of the system you're about to analyze and design. Architectural diagrams are usually topological—i.e., they show server nodes with their conceptual locations (whether local or remote, or the name of a particular site if known), and the proposed comms protocols to link the server nodes together. For example, Figure 4-1 shows a high-level architecture diagram for the VResorts Mapplet.

Sometimes the protocols may be a foregone conclusion (as in the case of the Mapplet, which was partly intended to showcase the ESRI technology, and had some decisions made up-front based on its predecessor, the Mapplet 1.0). One such decision was that the new Mapplet would use a Flex-based client UI to create a "rich client" user experience; this, in turn, suggested that Adobe's BlazeDS would be used for client<-->server communication. These sorts of decisions are never completely set in stone, but they tend to end up on architecture diagrams as a sort of hint to the designers.

Another way to look at this is that the requirements drive the architecture (as you'd expect); but occasionally, as we intimated earlier in this chapter, the architecture can also drive the requirements. For example, with the Mapplet, a big prerequisite was that the XML Service (an external hotel search system) would be used, as VResortswanted the ability to check pricing and availability in real-time. It was also known that ESRI would be providing the development team, who, in turn, would be targeting ArcGIS Server for the hotel mapping functions. While there was a lot of input from VResorts into the requirements and the UI, many of the requirements were driven by the capabilities known to be available in ArcGIS Server.

Mapplet architecture

Figure 4-1. Mapplet architecture

In Figure 4-1, the idea is that the user wants to search for hotels in the vicinity of a particular address or point of interest. So he or she browses a map (served up by ArcGIS Server), which is combined with a list of matching hotels from the XML Service. The Java-based Hotel Search Service returns these details to the Flex client.

The XML search is for "live" hotel data access, whereas the ArcGIS Server search is against a static copy of the hotel data that has been imported into its geodatabase. The geodatabase also contains landmark or "Point of Interest" (POI) data.

9. Agree on Requirements, and Test Against Them

Next, you should agree on business requirements, and then write tests in support of those requirements. As you'll see in the next section, the business requirements are sometimes driven (to an extent) by the already-known architectural constraints. However, for the most part, requirements tend to start out as an unstructured stream-of-consciousness from the customer: a long list of "what I want is" statements. It's the job of a business analyst to push back on these requirements and extract the real reason for them from the customer: to establish "why" as well as "what" (which customers tend to start off with). Often this pushing-back process can result in a different set of requirements, or a brand-new set being discovered. The business analyst then structures these business requirements into logically grouped areas, though they tend to remain throughout the project as a long list of "wants." As you'll see later in this chapter, it's worth doing further modeling on the business requirements to create behavioral requirements (i.e., use cases).

We cover requirements modeling and testing in Chapter 8; but, for now, here's a brief overview of the Mapplet requirements. The requirements were entered into Enterprise Architect (EA) and grouped into the following areas, or packages:

Functional Requirements
    |__ User Interface
    |__ Hotel Filter
    |__ Map

Figure 4-2 shows the Hotel Filter requirements, which led to the Advanced Search use case. The idea behind hotel filtering is to be able to declutter a map that shows a large number of hotels, in order to quickly and easily "zero-in" on a specific set of "filter" criteria. Mapplet 1.0 supported filtering against a set of amenities (pool, room service, etc.) and a few other categories. Mapplet 2.0's use of a live XML data feed allows us to include availability during a given time period, and filtering by price (which is not a static property of a hotel, but varies by date and availability and is continuously updated in something called the Global Distribution System).

Mapplet 2.0 Hotel Filter requirements

Figure 4-2. Mapplet 2.0 Hotel Filter requirements

Note

We'll return to the Mapplet requirements in Chapter 8, where we'll illustrate how to drive "customer-oriented" acceptance tests from them.

8. Drive Your Design from the Problem Domain

The "problem domain" is the area of knowledge that describes the business problem that an IT system will attempt to solve. Most commonly, the problem domain is captured in a domain model: a collection of names for things. The domain model can be shared between the customer, business analysts, and developers, and understood by all. It's created during a collaborative brainstorming session between the project stakeholders. The domain model's usefulness can't be underestimated: the requirements and architecture are written/drawn up using the names defined in the domain model; the developers will design and code the system using class names based on the domain object names; the tests will be based on the domain model, and so on. It's a common vocabulary that ties everything in the project together, and helps to eliminate ambiguity.[19]

Figure 4-3 shows the domain model created for the Mapplet project. This was a collaborative effort between the ESRI Professional Services team, and the VResorts customer.

During the OOAD process, your domain model will evolve into a detailed design: the domain objects become entity classes, with attributes (the data) and operations (the behavior) allocated to each entity (we recommend allocating behavior to classes according to a "responsibility-driven" thought process).[20] As we're focusing on Quick Search and Advanced Search, let's take a closer look at the detailed design for those two use cases.

Mapplet domain model

Figure 4-3. Mapplet domain model

Figure 4-4 shows an overview of the classes that together implement the Quick Search use case; Figure 4-5 shows an overview of the classes that implement Advanced Search. To shoehorn these two diagrams onto the page, we've hidden the attributes and operations, so they show just the relationships between classes. (We show the complete classes near the end of this chapter.) We're driving the design from the domain model by systematically and vigorously analyzing the use cases. The result is inherently domain-driven. As you can see from these two class diagrams, the entity classes evolved directly from the domain model.

Quick Search detailed design (attributes and operations hidden)

Figure 4-4. Quick Search detailed design (attributes and operations hidden)

Advanced Search detailed design (attributes and operations hidden)

Figure 4-5. Advanced Search detailed design (attributes and operations hidden)

7. Write Use Cases Against UI Storyboards

Over the next few chapters we'll focus on the hotel search part of the Mapplet, as this is really the core functionality. People use the Mapplet chiefly to search for hotels, by first zooming in to a particular location (or a "Point of Interest" such as a famous landmark, conference center, beach, or whatever they want to be close to), and then search for hotels in and around that location that match a more detailed set of filter criteria (e.g., star rating, amenities, price, and room availability).

One of the first steps during the requirements-gathering stage was to storyboard the new Mapplet, creating candidate screenshots of how the finished product could look. From this storyboarding session, it quickly became clear that searching would need to be split across two functions: a basic search and a more detailed step to further refine the search results. These two steps quickly evolved into two separate use cases, Quick Search and Advanced Search. Quick Search is used to pull up all the hotels in a desired location, and Advanced Search is used to "declutter" (filter) this display while checking availability, price, amenities, etc.

Figure 4-6 shows the storyboarded Quick Search created in Flash Builder and then imported into EA, linked directly to the Quick Search use case; Figure 4-7 shows the storyboarded Advanced Search. Near the end of this chapter we show the finished product: not far off the original storyboards!

Quick Search storyboard screenshot

Figure 4-6. Quick Search storyboard screenshot

Advanced Search soryboard screenshot

Figure 4-7. Advanced Search soryboard screenshot

6. Write Scenario Tests to Verify That the Use Cases Work

Use cases are behavioral requirements. While the business requirements can contain both high- and low-level, functional and non-functional requirements, the behavioral requirements are exactly that: a specification of the system behavior. Behavioral requirements are detailed descriptions of how the user and the system interact; because they are much more detailed, writing them helps to uncover holes in the business requirements.

The term "use case" has become rather nebulous, encompassing, as it can, a range of descriptions from the sketchy to the insanely detailed, including (or not) descriptions of the UI and target platform, pre-conditions and post-conditions, and templates several pages long. ICONIX-style use cases are, simply, an active-voice description of a user clicking and typing his way through a UI, and the system's responses.

Each use case is divided into "sunny day" and "rainy day" sections. There's always one basic course, or "sunny day" scenario: this is the user's default course through the use case, the "path most travelled." You should also expect to see plenty of alternate courses, or "rainy day" scenarios: these are the "paths less travelled"—things that can go wrong, or just alternative choices made by the user—which are often breezed over in many projects, but which can easily account for 80% or so of the system's functionality. If the rainy day scenarios aren't explored in sufficient depth before coding begins, all sorts of nasty surprises can leap up during coding, often resulting in a need to rethink the design. As a result, we regard modeling of the rainy day scenarios to be an extremely important activity, one that can mean the difference between project success and failure.

Note

There will be more about use-case scenarios (and their corollary, scenario testing) in Chapter 7.

For the Mapplet project, we divided the use cases into two packages: Displaying and Searching. Let's take a look at the Searching use cases (see Figure 4-8), as this package contains the Quick Search and Advanced Search use cases that we'll be focusing on. (In Chapter 6 we also look at Use Address, which is really part of Quick Search—as you can see in Figure 4-8, Quick Search invokes Use Address.)

The Mapplet use cases: "Searching" package

Figure 4-8. The Mapplet use cases: "Searching" package

Here's the complete narrative text for the Quick Search use case:

BASIC COURSE:

The system displays the Quick Search Widget, which contains several options for specifying an Area of Interest (AOI).

User double clicks on a Bookmark: Invoke Use Bookmark

User clicks Locate button on Address panel: Invoke Use Address

User clicks Locate button on POI Panel: Invoke Use Point of Interest

User clicks push-pin icon on Location Panel: Invoke Use Map Location Picker

The system updates the map extent and AOI based on the location. AOI is smaller than "Local View" limit.

System searches the static geodatabase for hotels within the specified AOI.

Invoke Display Hotels on Map

Invoke Display Hotels in List View

ALTERNATE COURSE:

AOI greater than "Local View" limit: System displays message: "Please zoom in further to display hotels."

No Hotels Found (and AOI within Local View limit): System displays message: "No hotels found."

"Show Landmarks" button is enabled: System searches the geodatabase for Landmarks within the specified AOI and displays them on the map.

User selects Pan/Zoom tools: Invoke Zoom-Pan on Map

And here's the complete narrative text for Advanced Search:

BASIC COURSE:

The system enables the Advanced Search widget when an AOI exists of "local" size. The user clicks the Advanced Search icon; the system expands the Advanced Search widget and populates Check-in/Check-out fields with defaults. The user specifies the the Reservation Detail including Check-in and Check-out dates; the system checks that the dates are valid. The user selects the number of adults from the drop-down menu (range: 1-6), and then enters the number of rooms from the drop-down menu (range: 1-number of adults). Optionally, the user selects desired amenities, price range, star rating, hotel chain, and the "hot rates only" check box. The user clicks FIND. The system searches for hotels within the current AOI, producing a Hotel Collection. Then invoke Display Hotels on Map and Display Hotels on List Widget.

ALTERNATE COURSES:

Check-out date prior to Check-in date: The system displays a user-error dialog: "Check-out date prior to Check-in date."

Check-in date prior to today: The system displays a user-error dialog: "Check-in date is in the past."

System did not return any matching hotels: The system displays a message: "No hotels found."

"Show Landmarks" button is enabled: The system displays Landmarks on the map.

User clicks the Clear button: Refine Hotel Search clears all entries and populates check-in/check-out fields automatically with defaults.

Note

The "Check-in date prior to today" scenario raises the question, shouldn't the UI prevent the user selecting an invalid date in the first place? Absolutely! But a big criterion of defensive coding is to ensure that each "tier" in the system guards against invalid data being passed through it. There will be more about this aspect of integration testing in Chapter 11.

To help make sure that the use cases satisfy all of the customer's requirements, EA includes a Relationship Matrix screen, which shows each use case in the selected package (down the left side) linked to its "parent" requirement (along the top). Figure 4-9 shows this screen for the Searching package (use cases) and the Hotel Filter package (the requirements).

Use cases linked back to their "parent" business requirements

Figure 4-9. Use cases linked back to their "parent" business requirements

You'd be forgiven for looking at the use-case scenarios and thinking, "Great! Now how on earth do I turn these into a design, ready to create unit tests and source code?" The conceptual design is the first next step: a brief exploration into an object-oriented representation of the use-case text. When you get good at doing conceptual designs, you'll be surprised how quickly you can create them—and they have the added benefit of identifying the key behavioral parts of the system that you'll want to write JUnit/FlexUnit/NUnit (etc.) tests for.

Note

There will be more about conceptual design in Chapter 6.

5. Test Against Conceptual and Detailed Designs

A "conceptual design" is a halfway house between the use cases and the detailed, code-level design that you're aiming for. The benefit of creating a conceptual design is that you get an early indication of whether the use cases have been thought through sufficiently: whether they're realistic and can be mapped to a design without too much kerfuffle. If it's difficult to map use cases to a conceptual design, then mapping them to a "real" detailed design would be even more difficult.

Another benefit is that a conceptual design helps to break the use-case scenarios down into logical software functions. These eventually map to one or more "actual" code functions; but by identifying the broader-grained logical/conceptual functions, you'll have created the ideal set of tests with which to provide just enough coverage of your codebase. These "controller tests" are like acupuncture points: they're strategically placed to test the flow of system state without having to test all the transitional stuff in between.

There will be more about conceptual designs and controller tests—in some ways the core of DDT (at least for programmers!)—in Chapter 6.

Having created a conceptual design and fed this back into your use case, possibly discovering new domain objects in the process and generally bolstering the behavioral requirements, it's time to evolve the conceptual design into a detailed design. There will be more about detailed designs and unit tests in Chapter 5.

Using the ICONIX Process, detailed designs are mapped out using class diagrams to show the static class structure, and sequence diagrams to show the event/response flow through the objects at runtime. The sequence diagrams are also used as a tool to allocate behavior to classes. In Chapter 5, Figure 5-1 shows the sequence diagram for Advanced Search.

So far we've been looking at things to do at the start of a project (or at the start of a new iteration with fresh new features to add to an existing system). The remaining sections in this chapter are about keeping the project on track once it's fully underway.

4. Update the Model Regularly

So the use cases are written, the design is done, the code and tests implemented, and the first development iteration is signed off, with software that's either released or (for an ongoing project) could be released now if the customer wants it. But what happens next? All too often, the next step is that the developers abandon all the work put into the model, and continue to write new code. The result is that the design becomes more and more out-of-date. We're sure you've worked on projects where this has happened. The moment one class is refactored and the design model isn't updated, there's a disparity between the model and the code. So the model, having become less useful, is used less, and so more code is written without updating the model; the model becomes even more out-of-date, making it less useful again. And so on. It's a feedback loop of the nastiest order.

Thankfully, modern tools support makes it actually pretty easy to avoid this trap, allowing you to get the full ongoing benefit of an up-to-date model, without slowing the team down on new developments. If you're using Enterprise Architect (EA), you'll be pleased to hear that EA has an add-in that goes by the rather unassuming name MDG Integration,[21] with versions available to integrate EA directly into Visual Studio and Eclipse (and, therefore, Flex/FlashBuilder). This enables round-trip engineering so that changes in the code are automatically reflected in the model.

Note

There is an article on the ICONIX web site that shows how to integrate your EA model with Visual Studio and sync up the model and code.[22] The steps involved for Eclipse/Flash Builder are pretty similar.

Figure 4-10 shows the Mapplet UML model (on the right) integrated into Flash Builder, with the Flex classes in the Package Explorer on the left. As you can see, there's the added benefit of having the original domain model (which should also include a definition of each domain object), requirements, use cases, and UI prototypes right there in the coding environment. Last but not least, the test cases are also right there.

If you double-click on a diagram in the Project Explorer, you'll get the "true" UML diagram showing all the class relationships, etc., within Flash Builder (see Figure 4-11).

The model and code doing a harmonious singsong

Figure 4-10. The model and code doing a harmonious singsong

The Mapplet Client UML model in Flash Builder

Figure 4-11. The Mapplet Client UML model in Flash Builder

If you prefer not to use tools support to keep the model and code in-sync, it's still worth allocating a small amount of time (say, at the end of a one- or two-week sprint) to revisit the model and update it in line with the code.

Figures 4-12 through 4-16 show some of the Mapplet classes reverse-engineered directly from the Flex code. If you compare them with the domain model in Figure 4-3, you'll see there's a pretty direct mapping.

Quick Search widget with all its attributes and operations allocated

Figure 4-12. Quick Search widget with all its attributes and operations allocated

Quick Search: classes for locating address candidates

Figure 4-13. Quick Search: classes for locating address candidates

The remaining Flex classes for Quick Search

Figure 4-14. The remaining Flex classes for Quick Search

Advanced Search widget

Figure 4-15. Advanced Search widget

Advanced Search: the ReservationDetail and HotelFilter classes

Figure 4-16. Advanced Search: the ReservationDetail and HotelFilter classes

3. Keep Test Scripts In-Sync with Requirements

It's a fact of life that the business requirements can change over the course of a project. The original customer representative might be replaced by someone who has a different perspective on what's needed; the economic conditions might change, leading to a shift in priorities; the BAs might realize that they misunderstood what was needed; the developers might realize that they misunderstood the BAs (although the process described in this book should help to minimize such misunderstandings), and so on.

When requirements do change, it's important to update the acceptance tests so that they always reflect the true, up-to-date requirements. A good set of acceptance tests is like a barometer of the project's overall health. If a lot of tests are failing, they're telling you that part of the system isn't being developed to the customer's specification. But if the tests don't actually match up with the requirements, then all you've got is a faulty barometer.

2. Keep Automated Tests Up to Date

As you'll see later in Part 2, it's important to make the unit tests and controller tests part of your automated build, so that when some code is committed, a complete build is triggered, including running the tests. If compilation fails because of the code just committed, the team is notified straightaway. Similarly, if the tests fail, the team finds out straightaway, and they're obliged to fix the tests (i.e., bring them up to date) in order to have a working build again.

Why such a draconian approach? It's simple: if the tests aren't run regularly and automatically, no one will ever bother running the whole test suite. As soon as a test fails, the team will become even less likely to want to run it, and it may even end up being removed altogether. So it's preferable to keep the tests up to date by making them run automatically.

That said, there are some tests that you may not want to run every single time a piece of code is committed to source control. Integration tests (which call external systems and thus tend to be quite fragile, dependent as they are on other teams, shared test data, etc.) and long-running tests would just make the build take all day, assuming it doesn't break on a regular basis (which it would, if it included integration tests), and they should be strictly kept out of the main build. They can still be run automatically, of course, but it's better to keep them on a separate run schedule: e.g., set them up to run overnight, or once per hour... as long as they're not connected with the main build.

We would also suggest that if you follow the ICONIX Process and DDT, with a design mapped out up-front based on a set of use cases signed-off by the customer, then you should find that code that has already been written and "finished" shouldn't need to be refactored over and over, as part of an "evolving design." Of course, you'd expect the design to change a bit: no design is ever set in stone, so you do need to be prepared to change things around if necessary. But the level of "design churn" should at least be greatly reduced.

1. Compare the Release Candidate with Original Use Cases

As seasoned software developers will tell you, "job done" doesn't just mean "have the release party." Actually, we hope it does mean that—an event of some kind gives a good sense of closure on a project or release. But first, before the project manager grabs the karaoke mic and does his best/worst impression of Tina Turner singing "You're Simply the Best," it's important to get some sense out of him—and the customer, the developers, BAs, and testers. Take one moment of sobriety and introspection before the desks are pushed to one side and the Dance Dance Revolution mat is unrolled. During this quiet moment, walk through the original use cases and compare them with the release candidate.

If there are significant differences, the customer might even feel that the project isn't so complete after all, and there's still work to be done before it can be released. That's a worst-case scenario, of course. A less drastic scenario is that the requirements shifted during development for one of the following reasons: (as we noted in "to-do" item #3) a shift in business priorities genuinely changed the requirements—in which case there's not a lot your team could do except modify the use cases and re-estimate the delivery date as the changes ripple through the design to the code and tests; the team didn't have a thorough understanding of the requirements or of the business itself when the project began; the requirements simply weren't analyzed in sufficient detail to create realistic use cases; the BAs didn't walk through the use cases and prototype UIs with the customer; there weren't any prototype UIs at all; the customer wasn't given the opportunity to review the business requirement tests and scenario test specs. In these cases, it's important to review the process and discuss what may have gone wrong, so that the same mistakes aren't repeated in the next bout of development or on the next project.

Importantly, the project review isn't a finger-pointing (or finger-wagging) exercise, and mustn't be approached as such. But it's a vital opportunity to improve your team's ability to create great software to spec.

Let's do a little release/use case comparison for the Mapplet. The Quick Search use case, if you'll recall from the start of this chapter, allows the user to jump to a particular place of interest on a map, and see hotels in that area. Figure 4-17 shows the finished product doing exactly that—in this case, searching for hotels in Waikiki. Figure 4-18 shows the results of the quick search.

The finished Quick Search use case: the user enters some basic search criteria.

Figure 4-17. The finished Quick Search use case: the user enters some basic search criteria.

Results of a Quick Search: that's a lot of hotels to choose from...

Figure 4-18. Results of a Quick Search: that's a lot of hotels to choose from...

Obviously that's a lot of matching hotels, so it's reasonable for the user to want to eliminate some of these. Enter the Advanced Search use case, which allows the user to declutter the map using price/amenity filtering. Figure 4-19 shows the user refining the search criteria; Figures 4-20 and 4-21 show the search results.

Advanced Search in action: the user refines the search criteria.

Figure 4-19. Advanced Search in action: the user refines the search criteria.

Advanced Search in action: we've decluttered the map, making it easy to choose a hotel.

Figure 4-20. Advanced Search in action: we've decluttered the map, making it easy to choose a hotel.

Advanced Search in action: the release matches the use cases, so we can take a vacation!

Figure 4-21. Advanced Search in action: the release matches the use cases, so we can take a vacation!

Of course, screenshots can convey only so much: we invite you to head over to www.VResorts.com and walk through the steps in the use case using the actual completed product.

If you compare these screenshots with the use cases from the start of this chapter, we hope you'll agree that they match up pretty much exactly—so exactly, in fact, that they look pretty much identical. There's a good reason for this: they are identical! But before you fill out a complaint card and mail it to our publisher, we would hastily point out that the reason they're identical is that the UI was storyboarded in Flash Builder, resulting in "non-functioning" MXML (in the sense that the event handlers were empty, and the application was bereft of code). Development then consisted of filling in the event handlers and writing ActionScript classes using a domain-driven approach, with unit and controller tests keeping the code well-behaved.

Summary

In this chapter we introduced the Mapplet 2.0 project and focused on two of its use cases, Quick Search and Advanced Search—really the core of the Mapplet functionality. We walked through our top-ten list of "project best practices." If you kickstart your project using these practices, it's a sure way to match up the team's understanding of what's required with the customer's real business requirements, and to ensure that the project starts off in the right direction.

We also compared the finished Mapplet with the original use cases—an important review step that should be carried out with the customer actively involved.

For the rest of Part 2, we'll walk backwards through the development process, starting with the finished code and design, to show how you write tests that validate and provide feedback on each stage.



[19] We demonstrate domain-driven design in the context of use cases in Use Case Driven Object Modeling with UML: Theory and Practice. Eric Evans's book Domain Driven Design: Tackling Complexity in the Heart of Software is also well worth reading. It's a pretty big book, though, so if you're in a hurry, check out the much shorter Domain Driven Design Quickly, by Abel Avram and Floyd Marinescu, available in print or as a free PDF: www.infoq.com/minibooks/domain-driven-design-quickly.

[20] For an excellent introduction to responsibility-driven design, see Rebecca Wirfs-Brock's book Designing Object Oriented Software and the more recent Object Design: Roles, Responsibilities and Collaborations.

[21] There is more information about MDG Integration at www.sparxsystems.com/products/#integration.

[22] See www.iconixsw.com/Articles/UML_visual_studio.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset