![]() |
Java Design:
|
This book is a book that teaches by example.
This first chapter teaches design activities by example.
These design activities can be done in any order. For this chapter, we've chosen this sequence:
If you already practice object-oriented design, then you might want to just scan this first chapter-and then proceed to the Java-inspired chapters which follow:
Let's begin.
This design approach consists of five major activities.
Please note that these are activities, not steps. If we could, we'd write all five sections in parallel columns, jumping back-and-forth from one section to the next.
In practice, we gain a lot of synergy by working back-and-forth between these activities. You see, each activity helps us discover new content for the other activities. Here's how.
The "Identify System Purpose and Features" activity helps us discover classes, understand UI needs, identify which scenarios are the ones to pay attention to, and grapple with what to include or not include within an object model.
The "Select Classes" activity helps us challenge the breadth of purpose and features, establish UI content, and provide the building blocks for scenario views and an object model.
The "Sketch A UI" activity helps us discover new purpose and features, find additional classes, identify some of the most significant scenarios, and work out the UI influences within an object model.
The "Work Out Dynamics with Scenarios" activity helps us discover variations on purpose and features, find additional classes, add detail (action buttons) to the UI sketches, and add substance-specifically, "must have" methods-an object model.
And yes, the "Build an Object Model" activity helps us discover additional purpose and features, classes, UIs, and scenarios.
The point? It's far better to apply these strategies synergistically. Each facet gets better that way.
The only way we know how to teach is by example, by example by example. It seems like we are in good company, though:
"Example is the school of mankind, and they will learn at no other."
-- Edmund Burke
"Example is not the main thing in influencing others, it is the only thing."
-- Albert Schweitzer
"Example isn't another way to teach, it is the only way to teach."
-- Albert Einstein
This book teaches by example, pointing out strategies and other important lessons along the way.
Actually, two examples are woven within the very fabric of this book: a business example and a real-time example.
If you are a business app developer: please study both examples. Carefully consider the business example. Then read the real-time example, to gain added insights on concurrency and notification.
If you are a real-time system developer: please study both examples. Read the business example first; that is where you'll find detailed "how to" strategies and discussions. Then study the real-time example, gaining additional insights into real-time issues along the way.
Let the games begin.
The business example which runs throughout this book is called, "Charlie's Charters."
Figure 1-. Charlie's Charters
Charlie's Charters is a small regional carrier, with small-aircraft service to nearby destinations. Sandpiper needs an application for scheduling flights and making reservations.
Begin by identifying the purpose of the system. What's this new application all about-its essence, its critical success factor, its unique selling proposition?
"Identify Purpose" Strategy: State the purpose of the system, in 25 words or less.
We talk things over with the manager of Charlie's Charters and establish this purpose:
Purpose: to describe flights, schedule flights, and make reservations.
Sometimes, it's hard to come up with a concise system purpose statement. When that happens, shift gears and develop a features list first; then prioritize those features; and then incorporate the most important features into an official-sounding system purpose statement. This works quite well, too.
What are the features for this system? Hmmm. Developers can get really (really) carried away with this, identifying feature after feature after feature.
How can we get to a meaningful features list?
Look for features which produce a desired outcome. The best features satisfy a "want" for the consumer who will be served by the system or a "want" for whomever is paying for the system.
Your customer will vote with his wallet. You need to deliver features which satisfy the "wants" of those two audiences. Adding extra bells and whistles, features which don't satisfy a "want," waste time, budget, talent-and profits.
"Identify Features" Strategy: List the features for setting up, conducting the business, and assessing business results.
Let's apply this strategy to the Charlie's Charters application.
Setting up
Conducting the business
4. Enter passengers.
5. Enter a reservation.
Assess business results
6. Does a scheduled flight have any room left?
(something which must be assessed whenever adding a reservation).
Together, we've defined system purpose and identified features-a good start.
Over time, we'll discover additional features and add them to the list. This comes from added understanding about what the customer and purchaser want; yes, as we build an application, we'll understand more about what features are really wanted, what features you could add to bring additional competitive advantage to the customer and to the purchaser. This is not feature creep! We can add features to your features list at any time. Yet until we commit to doing them, until you add a milestone for that feature in the project schedule, they are just proposed features, not committed-to features-a big difference.
With additional committed-to features, you might need to adjust the purpose statement, too. Change is inevitable. Early software development methods fought change ("the requirements are fixed and cannot be changed on this project"-a fantasy which is no longer possible in the fast-paced world we live in today). Effective object-oriented design embraces continual change. In building an object model, use PD classes to partition the data; use PD classes to partition the functionality, too. We can add new attributes (data), new methods (functions), and even new classes, without changing the overall shape of the model.
We've identified system purpose and features. What's next?
An object is a person, place, or thing. Yes, it's a noun. In software, it's a small piece of running software, with its own values and its own behavior.
For example, a scheduled flight object might have its own value (date = July 26) and its own behavior ("add reservation").
A class is a description which applies to each of some number of objects. In software, it's where you write application code, establishing:
what each object knows (its attributes)
who each object knows (its object connections)
what each object does (its methods).
It might also describe:
what the class itself knows (its class attributes)
what each class does (its class methods).
A class also describes:
how this class relates to others (its superclasses).
For example, a "scheduled flight" class might describe:
so each scheduled flight object can respond to the inquiry:
"Do you have room for another passenger on this flight?"
Here, we want to select some initial classes. This means we will look at persons, places, and things (objects) and form classes (descriptions).
Person, place, or thing? Let's expand that list a bit, covering the kinds of objects which we'll find again and again when building object models. Here is the strategy:
"Select Classes " Strategy: Feature-by-feature, look for: role-player, role, transaction (moment or interval), place, container, or catalog-like description. For real-time systems, also look for data acquisition and control devices.
Apply this strategy to the Charlie's Charters application:
1. Enter airports.
place: airport
2. Enter flight descriptions.
catalog-like description: flight description (flight number, arrival time,
departure time, and the like)
Figure 1-. A flight description
3. Enter scheduled flights.
transaction (moment or interval): scheduled flight
place: airport
4. Enter a passenger.
role-player: person
role: passenger
5. Enter a reservation.
role-player: person
role: passenger
catalog-like description: flight description
transaction (moment or interval): reservation, scheduled flight
6. Does a scheduled flight have room? (needed when adding a reservation).
transaction (moment or interval): scheduled flight
Figure 1-. Problem-domain classes for Charlie's Charters
We've established system purpose and features. Now it's time to sketch out a UI, the windows and reports for delivering those features.
First, list the key ingredients, the content we need. Then sketch a mockup.
"UI Content" Strategy: Feature-by-feature, establish content: selections, lists, entry fields, display fields, actions, assessments.
Apply this strategy to the Charlie's Charters application:
1. Enter airports.
primary selection and list: airport; airport list
2. Enter flight descriptions.
primary selection and list: flight description; flight-description list
secondary selections and lists: from, to; from list, to list
entry fields: flight number, from time, to time
actions: add a scheduled flight
3. Enter scheduled flights.
primary selection and list: scheduled flight; scheduled-flight list
secondary selection and list: flight description; flight-description list
entry fields: date
actions: has room?, add a reservation
4. Enter passengers.
primary selection and list: passenger; passenger list
entry fields: name, address, type (regular, gold, platinum)
display fields: number
5. Enter a reservation.
primary selection and list: passenger; passenger list
secondary selection and list: flight description; flight-description list
tertiary selection and list: scheduled flight; scheduled-flight list
display fields: date and time made, date and time expires
Here's a sketch for entering airports, fight descriptions, scheduled flights, and passengers:
Figure 1-. Mock-ups for entering airports, fight descriptions, scheduled flights, and passengers
Here's a sketch for entering a reservation:
Figure 1-. Mock-ups for entering a reservation
Based upon these UI sketches, add these initial UI classes to the object model:
Figure 1-. UI classes for Charlie's Charters
Work out the scenario views for setting up, getting things ready to go for making reservations.
Normally, we won't work out most "setting up" scenarios. Why? "Setting up" scenarios are fairly boring. Once we've worked out several of them, the pattern is pretty clear:
.create and initialize an object
.possibly send it to another object, to connect the two to each other.
In fact, the only reason we are including the "setting up" scenarios here is instructional. These are simple scenarios, good for first describing what scenarios are all about. These are often occurring scenarios; it's good for you to know what they look like, in case someone wants to see a simple example. And these are boring scenarios-ones that, once you see them, we hope you'll feel comfortable about skipping all together, spending more time on scenarios which will help you discover additional methods, additional classes, additional attributes, and additional features.
This scenario describes the time-ordered sequence of object interactions for building an airport window, followed by entering (adding, changing, or deleting) an airport.
It is in four parts: build (the window), add an airport, change an airport, and delete an airport.
Figure 1-. Build an airport window, then enter (add, change, and delete) an airport.
What about persistent storage? If we are working with an object DBMS, then the scenario view is fine as-is (the object DBMS provides the needed infrastructure for loading, searching, and saving airport objects). If we are working with a relational DBMS, then the scenario view needs an additional column, called AirportDM, responsible for interacting with one or more tables in the database. Working with relational databases is outside the scope of this book (if you are interested in this specific aspect of design, see [Coad97[ and [CoadLetter]).
Here are some details about scenario view notation.
The inner rounded rectangle represents a class. The outer rounded rectangle represents one or more objects in that class. In a scenario view, the outer rounded rectangle is pulled downward, so one can see a specific time-ordered sequence of object interactions.
Now take a look at the lower section. The horizontal lines separate the steps within a time-ordered sequence of object interactions. The bold horizontal lines separate little scenarios (a convenience, to get the most out of each scenario view). The arrows are messages, showing that an object in one column is messaging an object in another column. The arrows may be annotated with a little "c" (meaning, it is a message which is being sent to the class itself) or with a little "n" (meaning, it is sent to some number of objects in that class).
The comments section lists parameters, in this format: (inputs ; output)-along with whatever descriptive text might be needed for guiding a reader through a scenario view.
- delete the little "c" (and the space which follows it) from the comments section itself.
These two scenario views are just like the one you just saw. Only the class names and the parameters change.
Enter scheduled flights. The class names are ScheduledFlightUI and ScheduledFlight. That method's input parameters are number, from, to, departureTime, arrivalTime, capacity; the method returns a flight description.
We could add an AircraftDescription class, with attributes like model number, cruising range, and capacity. For now, though, let's consider capacity as the capacity for a scheduled flight. That's enough, at this point.
Enter passengers. The class names are PassengerUI and Passenger. The parameters are: (name, address ; passenger).
Once you've done one of the "setting up" scenario views, you really don't get too excited about doing them again and again.
There is a variation on this theme, though, with a bit more to it. Take a look at it next.
When entering a scheduled flight, one must select a corresponding flight description.
This same scenario view shape applies whenever we need to enter an object (in this case, a scheduled flight) and select a related object (in this case, a flight description, standard catalog information for that flight).
Again, the pattern is:
.create and initialize an object
.possibly send it to another object, to connect the two to each other.
Here is what this kind of "setting up" scenario view looks like:
Figure 1-. Add a scheduled flight.
Interesting-yet it's still not a scenario view we'd want to write down again and again.
We cannot document every scenario for an application. So we must focus on the ones which will give use the most added value, the most insights. Where do we find them? Read on.
Hopefully, we'll spend much more of our time with scenarios for "conducting business" and "assessing results" features. Why?
"High-Value Scenarios" Strategy: Build scenario views which will exercise each "conducting business" and "assessing results" feature.
Charlie's Charters example:
Enter a reservation.
Select a passenger.
Select a flight description.
Select a scheduled flight.
Invoke "add reservation."
If the scheduled flight is not full, add a reservation.
"Action Sentence" Strategy: Describe the action in a complete sentence. Put the action in the object (person, place, or thing) which has the "what I know" and "who I know" to get the job done.
Charlie's Charters example:
Complete sentence: Is the scheduled flight full?
Put the action in the object: scheduled flight.
Figure 1-. Add a reservation.
What happens when more than one reservation is being made at the same time? Could we get into trouble here, overbooking without knowing it? We'll take a closer look at this concurrency issue, in the "Design with Threads" chapter..
At this point, we've already developed a lot of content for an object model:
Indeed, it's good to build an object model in parallel with working out dynamics with scenarios. There is lot of synergy between an object model and its scenario views.
Here's the strategy:
But first, a few words about object-model notation.
Build an object model for the classes in the PD component:
- Class: Person
attributes: name, address
object connection: passenger
- Class: Passenger
attribute: number, type (regular, gold, platinum)
object connections (look-up paths): person, scheduled flight
- Class: Reservation
attributes: date and time made, date and time expires
object connections (look-up paths): passenger, scheduled flight
- Class: Scheduled Flight
methods:
class methods (apply across the collection of objects in the class):
new (add a new object to the collection of objects in the class)
instance methods: try to add passenger, has room, add passenger
attribute: date
object connections (look-up paths):reservation, flight description
object connection (message path): flight description
- Class: Flight Description
methods:
class methods: new
instance methods: add scheduled flight, has room
attributes: flight number, from, to, from time, to time
object connections (look-up paths): scheduled flight, airport
- Class: Airport
attributes: (three-letter) code, description
object connection (look-up path): flight description
Figure 1-. An object model-PD component
Note that the methods in the object model are exactly those methods we've added by working out dynamics with scenarios.
Methods like new, get/set, add/remove, and delete apply to every class with objects. Normally, don't show them in an object model; show them only when needed within a specific scenario view. Similarly, we are ignoring persistent storage mechanisms for the sake of clarity. Here too, common services like Save, Retrieve, Search, etc., are not always shown for the sake of brevity.
Here are some notes on Coad object-model notation.
Take a closer look at this symbol.
Figure 1-. The basic "class with objects symbol" and an example
The inner rounded rectangle represents a class. The outer rounded rectangle represents one or some number of object in a class.
By convention, class names are capitalized: the ScheduledFlight class. When referring to an object of a class, we don't capitalize it: a scheduled-flight object, meaning, an object in the class ScheduledFlight.
In these examples:
Each object in the class Class:
holds its own value for instanceAttribute, and
can carry out the instanceMethod.
Each object in the class ScheduledFlight will:
hold its own value for date,
can carry out the accessor methods (getDate, setDate), and
can carry out the hasRoom method
The class symbol is divided into three sections: class name, instance (object) attributes, and instance methods.
We can express the design graphically (object models) or textually (in Java code itself).
So what does ScheduledFlight look like in Java? It looks like this:
public class ScheduledFlight extends Object {
#
// attributes / private
private Date date;
// methods / public / accessors for attribute values
public Date getDate() { return this.date; }
public void setDate(Date aDate) { this.date = aDate; }
// methods / public / conduct business
public boolean hasRoom() {
// code goes in here }
#
}
The little scissors (#) symbols mark-out Java snippets-small and to-the-point excerpts of Java code, illustrating key concepts along the way.
Footnote: We prefer to limit access to all attributes, including class attributes: we make them private and insist upon using accessors. Consistent. Easy to follow. And hard to foul up. (Protected and private protected attributes remind us of named common attributes (variables? blocks?) in FORTRAN" ", or global variables in C; the inevitable problem is not knowing who mangled an attribute value-a real pain to track down.) This is the convention that we follow in this book (this is not a religious tenet; it's just the way we prefer to program).
Now consider an expanded version of the same symbol.
Figure 1-. An expanded "class with objects" symbol-and an example
The attributes section may be optionally divided into two sections: class attributes and instance (object) attributes. Class attributes are those attributes which have a value that applies across the collection of all of the objects in a class; if all flight descriptions had to abide by a "never to exceed" capacity, then we would need a class attribute; in practice, though, you will hardly ever find a need for a class attribute. (This generally occurs when your Problem Domain object model does not contain the "all-knowing" object who you might be able to ask such collection-level questions.) Instance attributes are those attributes for which each object in a class can have its own values.
The methods section may be optionally divided into two sections: class methods and instance (object) methods. Class methods are those methods which apply across the collection of all of the objects in a class; methods like new (create and initialize a new object and add it to the collection of all of the objects in that class), get list, and "find the object which matches this description" are class methods. Instance methods are those methods which each object in the class can do on its own.
Actually, the methods section may also be optionally divided into three sections-yet that is a subject for the chapter on interfaces.
In these examples:
Each object in the class Class:
holds its own value for instanceAttribute, and
can carry out the instanceMethod.
In addition, the class Class:
holds its own value for classAttribute
can carry out the classMethod.
Each object in the class ScheduledFlight will:
hold its own value for date,
can carry out the accessor methods (getDate, setDate), and
can carry out the hasRoom method
In addition, the class ScheduledFlight will:
holds its own value for totalScheduledFlights
can carry out getTotalScheduledFlights and setTotalScheduledFlights
(the "set" should be private, something that only the class itself
can invoke).
Again, we can express the design graphically (object models) or textually (in Java code itself).
So how can you express ScheduledFlight's class attribute and class methods-in Java? Take a look:
public class ScheduledFlight extends Object {
#
// class attributes / private
private static int totalScheduledFlights;
// class methods / public / accessors for class attribute values
public static int getTotalScheduledFlights() { return totalScheduledFlights; }
public static void setTotalScheduledFlights(int total) { totalScheduledFlights = total; }
#
}
Object connections provide lookup-paths and message paths. They establish the "who I know" aspect of an object's responsibilities.
If an object connection carries the added meaning of whole-part (assembly-part, container-contents, or collection-member), it gets a little triangle at the midpoint of the line, pointing to the "whole."
Object connection constraints are placed next to the object which is being constrained, the object which will eventually implement that constraint. (This is the opposite of entity-relationship markings of rows in one table corresponding to rows in another table-yet makes a lot of sense, when building effective object models. Worthwhile.)
Constraints include:
0-1 zero to one
1 one
n many
1-n one to many
[description] constraint special constraint
One more time: you can express the design graphically (object models) or textually (in Java code itself).
Consider the object connection between flight description and reservation:
Figure 1-. The object connection between flight description and reservation
So how can we show an object connection between a scheduled flight and its reservations-in Java? Use something like this:
public class ScheduledFlight extends Object {
#
// attributes / private / object connections
private Vector reservations = new Vector();
// methods / public / accessors for object connection values
public void addReservation(Reservation aReservation) {
this.reservations.addElement(aReservation); }
public void removeReservation(Reservation aReservation) {
this.reservations.removeElement(aReservation); }
// methods / public / get enumeration of reservations vector
public Enumeration getReservationList() {
return this.reservations.elements(); }
// methods / private protected / accessor for object connection vector
private protected Vector getReservations() {
return this.reservations; }
#
}
Code notes: We initialize the reservations variable as a Vector object, rather than null (the default). An alternative: we could initialize the variable with a constructor.
We limit visibility of getReservations to ScheduledFlight's subclasses. We let others gain access through an Enumeration.
public class Reservation extends Object {
#
// attribute / private / object connection
private ScheduledFlight scheduledFlight;
// methods / public / accessors for object connection values
public void addScheduledFlight(ScheduledFlight aScheduledFlight) {
this.scheduledFlight = aScheduledFlight; }
public ScheduledFlight getScheduledFlight() { return this.scheduledFlight; }
public void removeScheduledFlight() { this.scheduledFlight = null; }
#
}
Build an object model for the classes for the UI component, by applying the same "Build an Object Model" strategy. Here is the result:
Figure 1-. An object model-UI component
Note that each window has attribute pairs: a list of objects and then a selected one (or selected ones, in contexts which warrant multiple selections).
Take a closer look at those attributes. A list of objects? A selected object? They sound like an association, an object connection. And that is what they are-object connections that are shown with text. That's the best way to show an object connection from UI objects to PD objects. Why? Well, UI objects show a view of the PD objects, and consequently tend to be very interconnected with some number of PD objects. Using text makes this interconnection easier to understand (a picture is worth one thousand words; yet at times, a few words simplifies the picture).
How do these UI objects get the values they need? For the list attribute: A UI object sends a message to a PD class, asking for a list of its objects. Then the UI object sends messages to each object in that class, to get the values it needs to display. For the selection attribute: Someone makes a selection. And then the UI object knows the selected object.
Most methods in these UI classes begin with "invoke"-meaning, someone has just clicked on a button, to invoke some a corresponding set of actions. Also note that some methods are underlined, indicating that a corresponding scenario view has been defined for that (initiating) method.
At this point, the overall object model for Charlie's Charters looks like this:
Figure 1-. An object model for Charlie's Charters
A real-time example?
Please kindly note that by including a real-time example, we are not at all suggesting that we build time-critical real-time applications with Java-no way (not yet, anyway).
This book is about Java-inspired design, not about Java programming. The lessons learned here are applicable to design with other languages, too (notably C++, Smalltalk, and Object Pascal).
We include a real-time example here so we can (1) work with an example which engineers can more easily relate to, and (2) illustrate certain concurrency issues along the way.
The real-time example which runs throughout this book is called, "Zoe's Zones."
Figure 1-. Zoe's Zones
Zoe develops and delivers monitoring systems. The systems consisting of zones and sensors.
A zone is a collection of sensors, typically located within a room, floor, assembly line, building, or facility.
A sensor is a data acquisition device which reads values. For example, different sensors might detect temperature, pressure, smoke level, or motion.
This example is streamlined, offering just a few comments along the way. Different problem domain. Yet the same strategies apply.
Here we go.
Apply the same set of strategies presented earlier in this chapter (the strategies are listed at the end of the chapter too, for easy reference).
This time, it's for Zoe's Zones. Apply the "identify purpose" strategy:
Purpose: to monitor and track problem reports from sensors, grouped into zones.
Apply the "identify features" strategy to the Zoe's Zones application:
Setting up
Conducting the business
3. Activate zones and sensors.
4. Record problem intervals.
Assess business results
5. Assess sensor reliability.
Apply the "select classes" strategy to the Zoe's Zones application:
Setting up
1. Enter sensors.
data acquisition device: sensor
2. Enter zones.
place, container: zone
Conducting the business
3. Activate zones and sensors
data acquisition device: sensor
place, container: zone
4. Record problem intervals.
transaction (moment or interval): problem interval
Assess business results
5. View problem intervals.
transaction (moment or interval): problem interval
6. Assess sensor reliability.
data acquisition device: sensor
transaction (moment or interval): problem interval
Figure 1-. Problem-domain classes for Zoe's Zones
These symbols represent classes of objects for the software application.
Objects in these classes are abstractions-not the real thing.
A problem-interval object abstracts an interval of time between problem detection and problem correction. It is not an interval of time; instead, it is an abstraction of what the application knows and does about that interval of time.
A zone object abstracts a zone of sensors. It is not an actual zone; instead, it is an abstraction of what the application knows and does about each zone.
Similarly, a sensor object abstracts a sensor. It is not an actual sensor; instead, it is an abstraction of what the application knows and does to interact with an actual, physical sensor.
Figure 1- An actual sensor -vs.- an abstraction of what an application's responsibilities for interacting with an actual sensor
Apply the "UI content" strategy to the Zoe's Zones application:
1. Enter sensors.
primary selection and list: sensor, sensor list.
entry fields: number, interval
actions: activate, assess reliability
2. Enter zones.
primary selection and list: zone, zone list
secondary selection and list: sensor, sensor list
entry fields:
for zone: number, threshold
for each sensor in the zone: number
actions: activate, accept report (from a sensor)
3. View problem intervals.
list: problem interval list
Here's a sketch for entering sensors and zones:
Figure 1-. Mock -ups for entering sensor, entering zones, and looking at problem intervals
Add these UI classes to the object model:
Figure 1-. UI classes for Zoe's Zones
Work out the scenario views for setting up, getting things ready to go for monitoring sensors within zones.
Figure 1-. Add a sensor.
"Enter zones" follows the same basic pattern. The class names are "ZoneUI" and "Zone." The parameters are: (number, threshold ; zone).
Apply the "high-value scenarios" strategy to the Zoe's Zones application:
Hmmm. Apply the "action sentence" strategy here. We could tell a zone object to activate itself. And each zone object could tell each of its sensors to activate itself.
Figure 1-. Activate a zone and its sensors.
Figure 1-. Record problem intervals.
Figure 1-. View problem intervals.
Figure 1-. Assess sensor reliability.
Apply the "build an object model" strategy to the Zoe's Zones application:
Zoe's Zones:
- Sensor
attribute: number, legal range, operational state
(usually, a device object needs to keep track of its own operational state)
object connection (look-up path): problem interval
(if you needed the query: given a sensor, tell me its zone-then you'd need
a look-up path from sensor to zone, too)
object connection (message path): zone, problem interval
actions: activate, monitor (on-going behavior), assess reliability
- Zone
attribute: number, threshold
object connection (look-up path): sensor, problem interval
object connection (message path): sensor, problem interval
actions: activate, monitor (on-going behavior), accept report (from a zone)
- Problem interval
attribute: date and time detected, worst value, date and time corrected
object connection (look-up path): sensor or zone
object connection (message): --
action: calculate duration
Figure 1-. Object model-PD component
Should you consider two different kinds of problem intervals?
- Sensor problem interval
attribute: date and time detected, value, date and time corrected
connection: sensor
- Zone problem interval
attribute: date and time detected, value, date and time corrected
connection: zone
The two kinds of problem intervals are very similar. We could organize them with generalization-specialization, like this:
Figure 1-. Kinds of problem reports
Yet the only difference between the two specialization classes is the kind of (sensor or zone) .
Using specialization classes to describe what is nothing more than an enumeration of values-is definitely overkill.
Hence, for now, a problem-interval class will do the trick:
- Problem interval
attribute: date and time detected, value, date and time corrected
connection: sensor or zone, but not both.
The object connection between a problem report and its sensor or zone tells us what kind of problem report it is; so we don't even need an explicit "type" attribute (if and when we need to know, we can ask the connecting object whether it is an instance of sensor or an instance of zone).
Note the "[XOR A] 1" constraints. Here, it indicates that each problem interval object has an object connection to a sensor or to a zone, not both.
public class ProblemInterval extends Object {
#
// attribute / private / object connection
private Object reporter;
// methods / public / accessors for object connection values
public void addReporter(Object aReporter) {
this.reporter = aReporter; }
public Object getReporter() { return this.reporter; }
public void removeReporter() { this.reporter = null; }
#
}
Code notes: The reporter variable holds the connection to either a Zone or a Sensor. The class of object held in the connection can be determined by asking the object for its class.
Here is the UI component for Zoe's Zones:
Figure 1-. Object model-UI component
In this chapter, you've worked with scenario views and objects models for a business application (for Charlie's Charters) and a real-time system (for Zoe's Zones).
Along the way, you've learned and applied scenario-view notation (showing a time-ordered sequence of object interactions) and object-model notations (showing the responsibilities of each class of objects and each object within that class).
You've worked with these specific strategies for designing better apps:
"Identify Purpose" Strategy: State the purpose of the system, in 25 words or less.
"Identify Features" Strategy: List the features for setting up, conducting the business, and assessing business results.
"Select Classes" Strategy: Feature-by-feature, look for: role-player, role, transaction (moment or interval), place, container, or catalog-like description. For real-time systems, also look for data acquisition and control devices.
"UI Content" Strategy: Feature-by-feature, establish content: selections, lists, entry fields, display fields, actions, assessments.
"High-Value Scenarios" Strategy: Build scenario views which will exercise each "conducting business" and "assessing results" feature.
"Action Sentence" Strategy: Describe the action in a complete sentence. Put the action in the object (person, place, or thing) which has the "what I know" and "who I know" to get the job done.
|
Back to internet programming Links (ip-Links) page
Back to Java OO Design & Coding Standards (joodcs) page
Back to "Java Design" book page
Back to Table of Contents
Back to Introduction
Source http://www.oi.com/1.htm
On to Chapter 2 |
Home
|
Search
|
What's New
|
Workshops
|
Books
Software
|
Support
|
Free Goodies
|
Newsletters
|
Feedback