|
Building a UML Domain Model - Part 2
Last month I initiated a case study in a small hotel reservation domain. In that newsletter for Part 1, I identified a process for producing a domain class diagram:
I split Step 1 into two smaller sub-steps: Step 1a. Produce a list of "candidate" classes, then Step 1b. Challenge these candidates to eliminate those that are just simple attributes, synonyms, meaningless terms, etc. - that is, weed-out anything that does not merit "classhood". Step 1a produced the following candidate classes:
Step 1b. Challenge the Candidates Now we need to challenge these candidates, and identify the "real" classes in our domain. To accomplish this I ask 4 questions. These questions are applied to each candidate above with the purpose of eliminating from consideration all obvious non-classes. The four questions are:
The algorithm we follow is really simple: if we get a "no" to any question, we conclude the candidate is not a class and we move to the next candidate. Every "yes" takes us to the next question for a candidate. If we get "yes" to all four questions, we conclude the candidate is a class. Let's see how this works by applying these questions to some of our candidates. Candidate: Clerk 1. Is Clerk inside our system boundary? No. I stipulated in the first installment of this series that we only want to track the identity -- e.g., a name -- of which clerk makes a reservation. The human Clerk is an actor, or user of the reservation system, and actors are by definition outside the system boundary. Not a class. Candidate: Reservation 1. Is Reservation inside our system boundary? Yes. It is a central business concept. Next question. 2. Does Reservation have identifiable behavior? Yes. And if "yes" you should identify two or three potential operations (methods) that provide business value in our domain, and getters and setters don't count (I will qualify this below). I can imagine calling Reservation.Assign(aGuest), Reservation.Assign(aBedroom) and Reservation.CalculateCost(). Next question. 3. Does Reservation have identifiable structure? Yes. And if "yes" you should identify one or two attributes (data members) in the candidate. Question 2 informs us that Reservation should have a Cost attribute, and a reference to a bedroom and a guest. It would also have an ArrivalDate and NumberOfNights. Next question. 4. Does Reservation have relationships with any other candidates or "real" classes? Yes. From Questions 2 & 3 it is already clear that Reservation should have relationships with a bedroom, and a guest. Yes to all four questions - Reservation is a class. Candidate: Guest Information 1. Is Guest Information inside our system boundary? Yes, our requirements stipulated we want our system to maintain long-lived information about any guest who makes a reservation. Next question.
2. Does Guest Information have identifiable behavior? Yes, there is behavior we can identify, but they would seem only getters and setters. Should we then reject this candidate and move to the next candidate? Ahh..here we hit a bit of a snag, and why we have to use a light and "thoughtful" application of our challenges. Yes, we need to maintain guest information, but what is going to hold this information? The information is for a guest. So, should we infer a class called Guest to represent what this information is for? Is Guest an important concept in our domain? It would seem reasonable to do so to maintain the concept of a Guest making a Reservation. By allowing Guest as a class I can surmise behavior such as Guest.GetActiveReservations() which would return all current Reservations for a given guest, obviously not just a getter/setter method, and behavior of clear business advantage. Alternately, I could imagine a method in Guest called RevenueOver(aTimePeriod) to determine how much money we have received from a guest over a month, year, or other time period. Note that this example illustrates the singular fragility of this grammatical dissection approach: it is wholly dependent upon how the requirements are expressed. In our Use Case: Make a Reservation, line 3 was written as: "Clerk selects a bedroom and enters guest information." What if line 3 had been written: "Clerk selects a bedroom and enters information describing guest making the reservation"? In this latter version "guest" would have been a noun, rather than an adjective as in the former sentence. Next question, now using "Guest" as the candidate. 3. Does Guest have identifiable structure? Yes - at the very least all of the guest information, plus references to Reservation(s). Next question. 4. Does Guest Information have relationships with any other candidates or "real" classes? Yes, at least a relationship to Reservation(s). If we continue our challenge to each of our 12 candidates we will find the following real classes:
This is certainly a very small number of classes, but this series is about the process of identifying these classes. Now that we have found these 4 classes, we need to build our UML domain model. That will be the topic in next month's newsletter. Have a productive month, Gary K. Evans Agile Testing: A New Book Agile development can be confusing at one's first initiation. Starting a
project without all of the requirements, writing tests in
Their book is built around a unifying concept they call the Testing Quadrant. This concept carefully addresses each of the goals of various types of testing: some are technology-facing to support the programmers (e.g., automated unit tests and supporting tools), some are intended to support the team (e.g., automated & manual functional testing), some are business-facing (usability testing & acceptance testing), and some are developed in response to critique & requests for improvement of the product (e.g., when a customer provides feedback on the product's scalability, usability, etc.). If you are following an agile process, or have just been reading about agile, you know that the Prime Test Directive is: automate, automate, and automate your tests! Chapter 14 is a panoramic presentation of "An Agile Test Automation Strategy". It has already helped me make this transition simpler with a client I am working with this month. If you are confused about, or resistant to, the idea of test automation I believe this one chapter will illuminate the dark corners of your concerns. Chapters 17 through 19 discuss beginning, executing, and ending an iteration (sprint), respectively. A couple of highlights on test activity at the beginning of an iteration should suffice to motivate you to consider purchasing this book. What testing does QA do at the beginning of a sprint? The code hasn't even been completely written yet! Do the programmers just throw the iteration code over to QA at the end? Crispin and Gregory offer comments and examples from their projects to guide us. Here is a summary just from testing at the beginning of an iteration: The testers consume user stories and add tests that will validate the story has been implemented correctly. The Team then make their story estimates including performing these tests, because "no story is done until it is tested". The Team commit to a story only if they include the effort needed to conduct all of the tests. Testers collaborate with customers (or surrogates) to explore stories in more detail and begin defining high-level test cases that the developers will know their code has to pass. If you are involved in any way on an agile team, whether as designer, developer or tester, I cannot recommend this book highly enough. This one is going to be a classic. |
Subscribe to our newsletter! Send an email to You will find all prior About Evanetics Evanetics provides on-site consulting, training, and assessments for teams and management in Business Analysis, Object-Oriented Modeling, Project Definition, Iterative process, RUP, Agile principles and practices. Phone: 803-781-7628 Evanetics' Training Challenging times such as today can be the best time to enlarge the skillset of your people, so they will be even more prepared when our economy inevitably recovers. Here is a set of Evanetics' course offerings that may assist your organization: Agile Development with Scrum. For teams moving to Scrum, or teams who are finding agile development to be not so agile. Business System Analysis for Object-Oriented Projects. Business analysis and specification for the more technically-savvy system analyst. Thorough coverage of UML for the Business System Analyst. Writing Effective Use Cases. Written by Alistair Cockburn and based on Cockburn’s award-winning book, this course focuses exclusively on Cockburn’s approach for writing useful and effective use cases for any type of software project. Use Cases for the Rational Unified Process. Use cases according to the Rational way. Focus is on how to write useful and effective use cases, efficiently. Rational Unified Process Ver. 7. Describes the latest version of the Unified Process, the Unified Method Architecture, the 9 RUP Disciplines, and how RUP affects the major project roles in your organization. Use Cases to Code: Analysis with UML. Focuses on how to first represent “what” functionality object-oriented software systems will provide their users, rather than “how” the software will be designed. Use Cases to Code: Design with UML. Covers software architecture and software design in detail, including Gang of Four design patterns, Web architecture and Model-View-Controller, the evolution of Service-Oriented Architecture and Web Services, and how to develop a persistence layer for mapping classes to a Relational DBMS. Offshore & Off Course In line with this issue's topic of testing (and mixed with not a little hard-won cynicism), a column in this month's Visual Studio magazine brings home the real costs of offshore development and not testing properly. Alex Papadimoulis' Dev Disasters Column recounts a tale from Steve of how his company embraced offshoring with the usual mantra that "it is inexpensive". So they offshored a small project...that eventually became a 10,000 person-hour rewrite of their document management system, a major part of the company's main product. Then testing was offshored - it is inexpensive. And then first-line customer support was also offshored. Soon reports of anomalies started appearing: document changes were being lost. The offshore customer support declared "user error" and proceeded to inform the users how to save their documents - which the customers already knew how to do quite well, thank you. When the company's major client threatened to go to another vendor, Steve was assigned to research the issues. He and another developer eventually found two data declarations for disaster: public static string UserID; Static data. Read: global. Read: classic race condition. In this multi-user system, these data fields held the identifiers for the current (i.e., latest) document being manipulated, and saved. When user #1 and user #2 opened documents, the latest DocumentID was placed in this field. When the first user saved changes, then the second user saved, the latter overwrote the former. Hence, changes were not "sticking" - but only for some users, not the last to save. When the customers learned the defects in the code and its horrific design, many jettisoned the product and its vendor, others demanded refunds. And their bread-and-butter customer? They sued. But the offshoring was "inexpensive". I am not against all offshoring. My point in describing Papadimoulis' column is to remind all of us - managers, developers, testers - that sending our software overseas does not make our software better or safer. Offshoring successfully is more difficult and requires more effort than in-house development. I have worked with too many groups who have learned in the hardest possible way that if they cannot successfully run a software project between the 2nd and 4th floors of their own corporate headquarters, how could they expect to do it across 9 time zones, and 2 or 3 language and cultural divides? |
||||
|
Published by: Evanetics, Inc.13 Stonebriar Road Columbia, SC 29212 803-781-7628 Copyright (C) 2009 Evanetics, Inc. All rights reserved. www.evanetics.com |
|||||