Skip to content

Solutions to exercises – 2

Chapters 1 2 3 4 5 6 7 8 9 11 12

These are the solutions that were originally restricted to Addison Wesley approved lecturers and tutors.

Chapter 1

Question 1.4

There have always been those who would prefer to do the minimum of planning (including none at all) prior to coding. Recently, new positions have been introduced into the willingness-to-plan spectrum that runs from refusal, through resistance and acquiescence, to welcome. Agile modelers, XP (eXtreme Programming) moderates and XP extremists would be examples of new positions. Present the case for up-front analysis and design, and the case against.

The case for up-front analysis and design:

  • Building the right system
    One half of Barry Boehm’s succinct distinction of analysis from design. Not being clear about what the problem really is leads inevitably to a sub-optimal or useless solution. [Jerry Weinberg’s books are excellent sources of examples of this, especially “Are Your Lights On?” JD]
  • Understanding
    Just because you’re a programmer and you’ve been hired to work on an accounting system doesn’t mean that you understand double-entry bookkeeping. [This has probably improved over the years. The pride (unjustified) of the programmer has tended to reduce. The attitude, “I program computers, therefore I have a mystical ability that most don’t possess” has been steadily crumbling to a more realistic attitude. JD]
  • Consensus
    Almost as bad as misunderstanding the problem is unshared understanding of the problem. If we’re both working on solving a problem but I’m actually solving a different problem to the one you are, our solution must lack integrity.
  • Continuity, limiting the impact of change
    Systems are easier to understand and assess if there is a continuity between the shape and content of the problem, and the shape and content of its solution. We humans form model and analogs to help ourselves understand things. The more easily and more obviously that a software system is a model of something more meaningful to us than bit patterns in memory chips, the better. [We can’t use our senses on software. JD]
  • Building the system right
    The other half of Barry Boehm’s distinction. Creating a design up front gives goal and direction to the solution. In no other discipline than software “engineering” would anyone propose just piling up the bricks and hoping a nice building results, or that by moving the bricks around afterwards, the building can be tweaked until it’s tolerably useful.
  • Structure, work breakdown
    It’s impossible to allocated the building task and arrange their interaction if you have no overall plan or structure. Work will be duplicated and work will be forgotten.
  • Integrity and consistency across a system
    Without a guiding plan, there is a much stronger probability that the parts of the system built by different teams will follow different conceptual schemes, and future enhancers and extenders will have a much harder job. This isn’t quite the same as an earlier point on shared understanding of the problem; this is about shared vision of the structure and style of the solution.
  • Gauging and engaging
    When programming your own class, you simply must have available an accurate and dependable specification of the interfaces of the other classes and of the type system. This is impossible to achieve if everyone just lurches straight into programming.
  • Observable, debatable, communicable concepts and plans
    Designing and building large, industrial-strength systems isn’t easy. No-one can do it alone. Trying to debate and contrast the possibilities with nothing to point at but the code, is very difficult, whether it’s an internal monologue or a dialogue and so on. And the same applies to reasoning with our future selves.

The case against big analysis and design up front:

  • Most analyses and designs for software-intensive systems are of such poor quality that having them is worse than not.
  • Separating the specification from the building leads, in some organizations, to analysts and designers whose only skills lie in earning more and in advancement.
  • Sometimes there is such a disparity between the language and conceptual basis of the specifications, and that of the build technology, that one is put in mind of someone assembling a circuit board based on a document from a marketing “think” tank. [I blame, partially, an early overemphasis on analysis needing to be implementation-independent. JD]
  • Analysis paralysis
    Having perhaps encountered difficulty in overcoming the inertia of getting any analysis phase going at all, one then finds an enormous momentum to carry on analyzing forever.
  • Linear (waterfall) process models wrongly assume that it’s even possible to design without building. We, of course, no longer believe in linear process models. [I think this is one of the areas where the engineering analogies break down. It is possible to completely plan the building of a typical bridge from typical materials in advance of any building activities. As yet, this isn’t the case in software. JD]
  • Even spiral model development processes can suffer over-the-top, unworkable designs if their spirals, their macro management spirals, are too big. If big designs are done in the absence of any building (staged development, essential mockups, etc.) whatsoever, there is a strong danger that they will be unworkable. (From the Wiki entry on BDUF :
      “No plan survives its first contact with the enemy.” [Field Marshal von Moltke]
      “In preparing for battle I have always found that plans are useless, but planning is indispensable.” [Eisenhower]
      “The documentation is nothing; the documenting is everything.” [Gerald Weinberg].)

Question 1.6

Department Y of government agency X is going to replace their ailing port arrivals analysis and alert system. Chester Drawers Furniture Emporium wants to improve its operation; orders sometimes get lost, customer complaints are mis-recorded and unpaid bills are not systematically followed up, for example. Department Y currently uses a mainframe system written in APL. Chester Drawers have nothing other than people, paper and four-function calculators. Your consultancy is helping both organizations decide how to proceed. What kinds of analysis and design activities do you suggest would significantly benefit each organization?

The likelihood is that you will have to more than systems analysis for Department Y. It will be challenging to analyze their computer-based system, and anyway, it’s being replaced because it isn’t working. Trying to begin the modeling of a new system by analyzing an ailing and difficult to analyze, old, computer system is a non-starter. You would probably suggest that although there are certain to be algorithmic nuggets that must be extracted from the old system, understood, and possibly replicated somewhere in the new system, a subject matter analysis — ports, arrivals, threats, etc. — is where the structure and content of the model should begin.

Chester Drawers, on the other hand, is in a situation that is closer to the computerization era where a lot of our systems development ideas and techniques began. It will be beneficial to do a significant amount of systems analysis, and probably a little subject matter analysis as well. A good systems analyst doesn’t just analyze; (s)he goes on to improve the system. And how does (s)he do that? In part, it’s by developing an understanding of the problem the system was trying to solve.

Chapter 2

Question 2.5

(You may already have done a similar exercise to this one, in the previous chapter. You might consider it worthwhile to do another; then again you might not.)

Think of four different subject matters – preferably ones you are familiar with, and preferably not those of the case studies (catering and crime). Think of four entities (relevant, subject matter objects) for each subject matter. Ask yourself if your entities actually do anything. If an entity does do things, list a couple of its example actions. Now check once again that your entities truly are there in the subject matter and that their actions are as well; assure yourself that you haven’t made anything up.

If you have enough object-oriented programming experience, picture some Java, C++, etc. objects carrying out the same actions as their subject matter counterparts and ask yourself it that would be reasonable. This book says that it wouldn’t. If you currently have little experience of object-oriented programming, return to these lists when you’ve more.

The kinds of subject matters I’ve worked on included:

  • Personnel: Department, Timesheet, Employee, Qualification Granting Body
  • Accounting: Invoice, Customer, Petty Cash Account, Balance Sheet
  • Theatre Seat Reservations: Seat, Performance, Booking Fee, Payment
  • Radar Operator Training Simulator: Cloud, Obstruction, Beam, Reflection

I’ve listed some of their entities. Several of them don’t do anything at all. A Timesheet, an Invoice, a Petty Cash Account and a Balance Sheet, for example, don’t actually do anything at all. Pushing at the limits of credulity, a theatre Seat sometimes flips to its vertical position, leading to potential embarrassment if one hasn’t noticed; as well as failing the test of relevance however, this would also fail to be something sensible for a software Seat object to do.

A Qualification Granting Body issues a qualification, for example; but would its counterpart Java or C++ object do anything similar? No. Even if the systems between the Qualification Granting Body and ourselves were completely automated, the qualification would still arrive out of the blue, over the wire, and not be created by our Qualification Granting Body object.

What does a Customer do. They buy things and they, hopefully, pay their bills. Neither of these would be sensible instance methods (non-static member functions) for a software object.

A Performance does lots of interesting things. It entertains. It gets rave reviews or Golden Turkey awards. Once again, these are not sensible things for the Java or C++ objects to do. Am I just picking the silly examples? No, it wouldn’t matter what you picked. What about the performance generating revenue? Well it doesn’t — that’s a fabrication (sometimes justified by calling it an abstraction). The performance attracts people and the people stump up the revenue.

In the Radar system, the real Cloud absorbs some of the radiation from the radar transmitter and reflects some of it back. In the software, however, we will have to calculate the amount of reflected radiation, and that calculation is more likely to be done by the beam, receiving the cloud as argument, or, even more likely, by a calculation object whose existence and nature will be pure invention.

[What about subject matter entities that have things done to them. Some early methods advocated modeling the actions suffered or performed by subject matter entities (or real world entities as they might have been called.) We could say that the Invoice suffers (or enjoys) being paid. But, again, that’s no clue as to what methods or member functions the counterpart software object would have. Something else would probably message the Invoice that it had been paid, on such-and-such a date. And that something else, isn’t going to be a Customer object; it’s going to be something like a GIU (graphical user interface) invoice object, that we are not going to be programming up unless we’re completely mad masochists. JD]

Question 2.6

Consider the subject matter entities from the previous exercise. List a couple of the measurable properties (attributes) of each entity. Again depending on whether or not you have enough experience of object-oriented programming, ask yourself now or later whether or not the software objects would reasonably exhibit the same properties. (This book says they will.)

Picking up the example from earlier (Chapter 1, exercise 5), the DVD entity found in our rental shop subject matter would have measurable properties of rating, and loan period, and it would seem entirely reasonable that any Java or C++ DVD object would happily respond to the messages rating() and loanPeriod().

The Performance from the Theatre Seat Reservation system has a date and a time in the real world. And these are eminently sensible things to turn into query messages for its object counterpart to answer.

Any and all relevant attributes of relevant subject matter entities will suggest reasonable query messages for Java, C++ or Smalltalk objects. They would suggest reasonable properties* for Object Pascal, C# and CORBA objects:

  • Department: name, code, budget, …
  • Timesheet: period (but not the contents — the entries would be better off as related entities with their own attributes) , …
  • Employee: name, postal address, age, …
  • Qualification Granting Body: date established, postal address , …
  • Invoice: date issued, amount excluding taxes, number, …
  • Customer: formal name, postal address, date established, …
  • Petty Cash Account: nominal ledger account number, maximum limit amount, …
  • Balance Sheet: nominal ledger account number, …
  • Seat: row (although this might be better as an entity in its own right), number, …
  • Performance: date, start time, …
  • Booking Fee: monetary amount, …
  • Payment: date received, amount received, …
  • Cloud: position, density, …
  • Obstruction: position, density (so some opportunities to generalize)
  • Beam: energy, width, …
  • Reflection: energy, start time, end time, …

Question 2.9

In the context of object-oriented software engineering, define type and define class. Compare and contrast the two.

“Type” is generally taken to be a notion that describes and specifies interchangeability. Two object instances have the same type if they can both serve their clients interchangeably. For good, ordinary object instances, this means that they accept the same set of messages. We normally extend this to include intentionality rather than just coincidence. (And an object is of a subtype if the messages denoted by the supertype are a subset of its accepted messages.)

“Class” is much harder to define. It varies from language to language. And even within a language (particularly C++) a class can be put to a large number of quite diverse uses. In the Smalltalk language, simplifying a tiny bit, a class is just an object that specializes in defining and making other objects. So the only general-purpose definition of class that I can come up with is: a means for managing object instances.

Type then is an external perception and class is both an internal and external perception. Type is of interest to the client end of a message, whereas class tends to be of interest to the server end. Variables (and parameters and returns) have types; objects come from classes. In nearly all everyday OO languages, an object can exhibit several types but is instantiated from just one class. A concrete class is a class and a type, but it’s usually a poor type. An abstract base class is a class and a type, and is a slightly more useful type. We got into so much trouble with base classes (superclasses) however, that today we tend to prefer purely abstract base classes (pABC) for our types, or in more modern languages, interfaces for our types.

* These languages (Object Pascal, C# and CORBA’s IDL have a device called a property: a value that can be exhibited to the outside world independently of whether or not the object actually stores the value within.

Chapter 3

Question 3.2

What packages would you use in order to organize the development of a system for a video and DVD rental store? What influenced you in your choice of packages?

Here, I was influence by re-use. I pictured hawking my software around all the different shops and enterprises in the locality. I would want the maximum likelihood that units of development could be units of sale. I also thought about the overall mission statement and how it would it have some glaring “and”s. And, of course, terminology would also have given clues — accounting has different terminology to entertainment.

  • Resource management (DVD, video, game, …)
  • Customer management (personal details, membership and subscription, …)
  • Merchandising (soda, Pringles®, blank DVD-Rs (or perhaps that wouldn’t be such a good idea), …, i.e. stock system)
  • Money handling (i.e. accounting)

Question 3.3

Consider POLLY, the computer system to help the owners of small to medium sized hotels with their administration. Write the mission statement (or statement of purpose) for such a system. It might help to imagine you are marketing or selling the system. Assess the focus or cohesion (and completeness and honesty) of your mission statement. If you feel that it is incohesive or diffuse, propose some packaging for the system and write a mission statement for each package, again assessing the focus and cohesion.

A first mission statement might go like this:

“A system to accurately and optimally book and bill guests and rooms; and to control stock, in a very easy-to-use manner; and to schedule and record repair and maintenance work; and to support administration by, for example, printing breakfast lists and room cleaning lists.”

[Of course, those “and”s are the obvious giveaway. I put them all in purposely; but they might well be implicitly there and a bit harder to spot. You may have had more. The initial introduction did mention banqueting and conferencing, which might well be within the interests of medium-sized hotels. JD]

The mission statement does lack cohesion and focus, so we plan some packaging and form a mission statement for each package:

  • Guest
    • Booking — To accurately and optimally book rooms
    • Billing — To invoice for accommodation and sundries and record payments thereof
    • Scheduling — To print, for example, breakfast room lists, room cleaning lists
  • Stock control — To control stock in an easy to use manner
  • Fixtures and fitting — To control maintenance tasks via repair requests, scheduling, reporting and completion

The ensuing mission statements are much more cohesive and focused.

Chapter 4

Question 4.1

The chapter text has already mentioned the spreadsheet as an example of a tool that enables computers to solve problems without programs needing to be written. Describe a couple more situations where one would typically and wisely be able to use a tool rather than writing programs.

Can you think of any situations where one might be tempted to use an unwise choice of tool, and why?

Writing a GUI by hand would, today, typically be reserved for programs with very unusual needs and probably a very large numbers of users. Many, many systems would employ a GUI-building tool instead.

There are many data-processing situations where hand-writing code to understand (parse) linearly available data would be unnecessarily time-consuming and take an unnecessary risk that it wouldn’t work properly. Lexer compilers and parser compilers would typically be a better route to take. [But that was mentioned in the book several times, so let’s think of another example. JD]

With a standard database, a relational database for example, one would expect to use a report generator for typical reports. Hand-writing programs in general-purpose languages using API calls, or hand-writing SQL would typically be unnecessarily time-consuming and error-prone.

[And good GUI builders and report generators work in languages that are close to the problem, rather than a general-purposed programming language. A graphical user interface builder should probably work — graphically. A specification of a report should look like a report. Just like a web page specification should look, at least a bit, like a web page. JD]

There are classic examples of tools that vendors try to sell us that, in many people’s experience, look seductive but that don’t bring benefit; indeed that sometimes reduce a project’s chance of success. These kinds of things also figure in lists of “silver bullets”. A general purpose code generator is the “tool” I have in mind. Application-specific code generators can work well, but I don’t believe that a project, having failed to find a specific tool, and not able to summon up the will-power, budget, expertise, or whatever, to plan and write some good code, should turn to a general-purpose code generator, such as those that come as part of CASE tools, for example. I have similar doubts about the other-than-trivial benefits of reverse engineering tools.

Chapter 5

Question 5.1

How many different kinds of requirements can you think of? List them. For example, you might include functional requirements and security requirements.

  • cost
  • functional
  • timescale
  • availability
  • reliability and robustness
  • usability
  • speed
  • security
  • compliance and conformance
  • legal
  • environmental
  • ergonomic
  • social and political

Question 5.2

Classify the following requirements using your answer to the previous question. You can improve your answer to the previous question if necessary. (I am sure that the wording of these requirements could be improved as well.)

  • “The system must never be unavailable for more than three minutes.”
    – availability
    (“The system must never be continuously unavailable for more than three minutes, nor unavailable for more than a total of ten minutes in any 24-hour day (using local time).”)
  • “The machine room must have less than 0.1 ppm ozone.”
    – environmental
    (“The machine room must have less than 0.1 ppm ozone, averaged over its entire volume and averaged over any ten minute duration.”)
  • “The system must calculate the optimum angle of attack for the aft hydrofoil.”
    – functional
    (Optimal for what? I don’t know enough naval engineering to say, but I’d want to find out.)
  • “The system must be operating to the downtime requirements by 0001 hours 11 December 2003.”
    – availability
    (“… by 0001 hours 11 December 2003, UCT.”)
  • “The system must pass a FAST (Federation Against Software Theft) audit – no unlicensed software for example – and must not require registration under the Data Protection Act.”
    – legal
  • “The system must play back at least 48 tracks of 24 bit/96 KHz uncompressed audio data, with one digital effect (e.g. reverb) per channel, simultaneously.”
    – functional

Question 5.3

Break the following scenario down into “atomic”, i.e. irreducible requirements:

“We would typically call up yesterday’s menu. We would check with Chef to see if any particular stock items need using up via any particular dishes. I guess that maybe the system could help us with alerts as to any expensive stock approaching its use-by date. We would amend the menu to remove dishes not on offer today and to add the new dishes like the stock-using dishes and any other dishes that the manager or Chef have planned.”

(You) “Would you type up the details of each new dish?”

“Well I guess there might be totally new dishes; but mostly we would want to call up some kind of overall dish list, where the typical price, description, etc. was already entered. Sometimes we would have to amend the defaults – for expensive ingredients whose prices fluctuate wildly, for example.”

(You) “And would you be changing yesterday’s menu to become today’s? Or would you be leaving yesterday’s menu on record and creating today’s from it?”

“Oh, we would definitely want to keep a record of previously used menus; we’d simply be using yesterday’s as a typical starting point. I imagine there would be times, though, when we’d create a menu completely from scratch.”

The system must/should:

  • locate the menus used on a given date, and warn if the number of qualifying menus isn’t exactly one.
  • display [please see interface/look/feel requirements section] a selected menu.
  • create a new menu by copying a selected, existing menu.
  • note dish(es) selected from a selected menu.
  • remove selected dish(es) from selected menu.
  • locate any dishes including those that are not necessarily related to any menus.
  • support the specification and creation of new dishes.
  • register and record changes to the specification of an existing dish.
  • register and record the addition of a selected dish to a selected menu.
  • record the details of the menu used on a given day (including but not limited to the details of the dishes it offered).
  • create a new and empty menu from scratch, ready to accept any dishes that will be selected for it.

[I have left these pretty much in the order in which they occurred to me as I read the question. JD]

The system could/won’t:

  • according to a chosen periodicity, indicate (for example by printout) the stock item batches satisfying previously recorded criteria (including but not necessarily limited to stock item batches that will expire within an established time period).

[I decided to list the speculative requirement (or “change case”) separately. JD]

[I, like many of my students, was tempted to put down that the system would help select the dishes that could use up the ingredients that were about to go off. But there’s no evidence for that. That would be fantasy and a rod for my own back. JD]

Question 5.6

(Difficult) Quantify the following requirements. Come up with numbers that the system-to-be can be measured against in order to establish if it has met the requirement.

  • “The data shall be more consistent.”
    A bison (version 1.875) compiled parser to transform our data into valid (quinge.dtd version 2.2), well-formed XML should be directly feasible and have no more than 83 terminal symbols and require no more than 300 grammar rules. (I.e. Assessing or establishing the complexity of a parser written to reformulate this data, into XML for example.)
  • “The system must register the details of a booking request.”
    … confirming that the details have been stored within 3 seconds, with a throughput of at least 20 bookings an hour, such that parsable fields — for example, hour of booking and minutes past the hour of start time — could be extracted. (I.e. working on the words ‘register’ and ‘detail’.)
  • “The system must portray in a readily-assimilated fashion, the selected statuses (for example, location and/or readiness and/or …;) of a flexibly selected sets of active personnel (for example, an individual, all personnel matching an input declarative query (e.g. SQL), or all active personnel).”
    The system must portray … such that Comprehension Test 12a from Appendix B of document 2004-08-19_fullReq.doc is passed with a score of greater than 89% by 8 out of 10 randomly selected (see Appendix D of document 2004-08-19_fullReq.doc for randomization and selection procedures) full-time booking agent employees. (I.e. establishing the time taken to form a mental picture good enough that a comprehension test could be passed with a required degree of accuracy.)
  • “Usability is our number one priority.”
    [This one defeated me. I went to [Principles of Software Engineering Management, Tom Gilb, Addison-Wesley, 1988, 0-201-19246-2.] and discovered how he thought about it and broke usability down into things that could be measured: JD]
    “- Level of personal ability required to enter training course for product
    – Training time required to attain a pre-determined level of productivity with the product
    – Specified amount of work to be produced by a person so trained
    – Rate of errors made by a trained user, operating at the normal work rate
    – The opinion (survey) of the users of the product as to how well they liked it.”

Question 5.8

What are the subject matters for the following computer packages: a word processor, desktop publishing, a sales ledger and vehicle number plate recognition?

The subject matter of a word processor is writing (editing) and the written (printed) word. When searching (years ago) for inspiration as to the beginnings of the structure and content of a word processor, one would have considered the structure of text — such concepts as letters, words, hyphens, dashes, stops, line endings, sentences and paragraphs; and nature of the output media — such concepts as screen width and height, paper width and height, paper margins and page numbers.

[I am harking back to earlier, pre-bloatware days here. A “word processor” from the dark empire today seems to add, for example, the world-wide web as a subject matter. JD]

[It’s interesting to think about our other route into a development during the early stages — something that I will make more of if there’s a second edition — metaphor. There would have been at least two obvious, candidate metaphors: writing by hand and writing by typewriter. We, sensibly, chose the typewriter as our metaphor, with, for example, tab stops. I remember, however, at several times during the last 20 years, people jumping up and down excitedly about “pen” computing. Despite all the hype though, it’s pretty clear that hand writing is the less useful metaphor. Yes, if I am holding some device and only have one hand, or if the device is small, hand writing is the appropriate metaphor. If there is some desk space available, however, most people would consider hand writing a severely backward step; surely only the one-fingered, hunt-and-peck-would-be-a-major-advance, brigade would use hand writing with a computer. JD]

The subject matter for DTP or desk top publishing is, of course, publishing. This would be an example of a subject matter so vast that clear requirements would be absolutely essential in providing boundaries. They would lead to a subset of publishing that would include word processing, computer graphics, typography, typesetting, pre-press, printing, binding, indexing, numbering, …

The subject matter of the typical sales ledger works would be financial sales accounting and credit control.

A vehicle number plate recognition system addresses the subject matters of national vehicle registration marks, typography, image processing and pattern matching.

Chapter 6

Entities

Question 6.3

You are part of a team working on the subject matter model for STREPT – the module registration system mentioned in Section 1.3.3. You have been specifically asked to explore the following requirements:

  • The system must register student details, including at least home-time address and term-time address.
  • The system must register course details, including but not limited to name, course code, credits needed, department responsible and duration in weeks.
  • The system must register the modules that make up a course including, but not limited to, name, description, credits available, duration in weeks and prerequisite modules.
  • The system must register a student’s choice of modules for a course.
  • The system must register faculty and departmental defaults for student, course and module details. For example, the Engineering faculty default for a student’s preferred notification route is email, whereas the Social Science department’s default for the same thing is letter.
  • The system must register specific details concerning a single presentation of a course or module, for example, starting date.
  • The system won’t concern itself with validating modules against courses (invalid combinations, for example). For the initial version(s) of the system, that will be done prior to input to the system, although the system may well take over that role in some future version.
  • The system must route messages to students and keep a record of the message (e.g. library hours during vacation time) and the route to the student (e.g. term-time email).

Using the considerations and criteria from the chapter, what entities would you initially choose? Decide on up to about four attributes, with attribute types for each entity. While you are listing entities and attributes (there’s not much point in doing a diagram at this stage), make notes about any association (or other) relationships you anticipate having in the model.

It may well be that your choices overlap with part of another team member’s work; that’s OK, your team is planning to have a rationalization and consistency pass later. Think of your job here as something of a brainstorming entity choice. (The word entity is being used in the same way as it was in the chapter. If you prefer to say “class”, that’s OK, but you are looking for classifications of “subject matter objects”; you are not planning or inventing software classes.)

Student
  family name : string, forename : string, age : natural number, sex : enum{female, male}, (and in relationship with addresses)

Home Address
  postal address : string, post/zip code : string, email address : string, telephone number : string

Term-Time Address
  postal address : string, post/zip code : string, email address : string, telephone number : string

  [But see below. JD]

Course
  formal name : string, familiar name : string, code : string, URL : string
  [I’ve noted several likely relationships for course. Were you tempted to have department, etc. as attributes? We don’t want to model something twice, so if department is an entity (exhibits identity) then a course’s department is best modeled with a relationship. JD]

Department
  formal name : string, code : string, URL : string

Module
  formal name : string, code : string, expansive description : string, credits available : natural number, duration in weeks : natural number, (modules seem to be related to modules, as well as being related to students)

Faculty
  formal name : string, URL : string

Presentation
  start date : date, duration in weeks : natural number
  [I couldn’t discern any more than these two attributes. That’s OK. There are entities that are characterized more by the identities of the instances they are related to, rather than by the values of their attributes. And with more information, more might appear. Resist too much invention, however; difficult with an exercise where there’s no possibility of asking clarifying questions, of course. JD]

Message
  content : string
[I did go back to the domain experts and uncovered a missing requirement about bandwidth, which eventually led to a maximum length property for the content attribute. JD]

Transmission
  medium : enum{email, letter, fax, call, SMS}, date sent : date (and a relationship to an address)

[Transmission appeared on my initial list with a question mark against it. It was when I started to do the attributes of message that I became convinced that it was an entity. Originally I called it “Route”, but everyone got confused because, in other campus systems, much is made of “Study Route”. JD]

[Address is often an interesting one. It is often modeled as an attribute at this stage, as it often exhibits no identity, i.e. no individuality. However, most object-oriented designs eventually take the purely technical decision to implement address as an object, later. Here, address does seem to exhibit identity and is, we suspect, going to be in a many-to-one relationship with student. So I’ve modeled it here as an entity. And the address entities have been given postal address attributes with type string (or text if you prefer); telephone number and email address are shown as strings as well. Personally, I think analysts have already wasted too much time attempting to define address, telephone number and email. Unless a situation throws up something unique, I use the types postal address, telephone number and email. If I want/need to insult my designers, I include a note saying that they should probably be objects in the implementation. JD]

[There is clearly something in common between home- and term-time addresses. What will we do about that? If you know about it, you might be tempted to say, “generalize!” I don’t think that’s necessary. As you are going to find out if you haven’t reached the next chapter yet, I prefer any use of generalization to strongly justify itself. And it’s not necessary here. My next decision was to change to one Address entity and two relationships. We are anticipating, somewhat, an exercise coming up shortly and also an exercise in the next chapter. JD]

[I’ve been careful with names. I hope you have. For example, there were many places where I could have named an attribute “name”; but I’ve tried to do better than that. JD]

[As noted in the book, I’ve used the term “natural number”. You may prefer positive integer. (I don’t like “int” at this stage however; although it’s minor (obsessional) point. JD]

[As noted in the book, units are vexatious. One can add attribute properties to the model repository (data dictionary) for “default unit”. One can use the name, as I’ve done; respecting the requirements, being precise and allowing the designers to be cleverer if they deem it appropriate. If handling units was a critical requirement, then I would figure units into the model, probably using an analysis patter (as it’s a commonly recurring modeling problem). JD]

Attributes

Question 6.5

Think of at least two ways of defining the type of the attribute eyesight. It was an attribute of Witness in the text.

20/20 numeric style or, more likely, enum {average, good, short, long, astigmatic, blind, unknown}

Relationships

Question 6.6

Explain the difference between the interpretation (conventional) of a multiplicity of 1.. and the interpretation (this book’s and many others’) of aggregation’s distinguishing feature.

When developers demand a more useful definition of aggregation than is often given (even in the UML itself), we often use “existence-dependence”. Let us assume that we do choose to use that as our bottom-line distinguishing characteristic of aggregation.

  • A diamond at one end of an aggregation relationship means that the instances (not class) at the other end of an instance of this aggregation relationship would not exist were they not engaged in that role (of helping “form” the instance at the diamond end). Aggregation says something about the characterizers (and the characterized).
  • A multiplicity with a minimum of one (1..), on the other hand, indicates that the instance at the other end would not be a valid instance should the associate at the 1.. end not be there. Mandatory multiplicity (1..) says something about the characterized.

I have assumed, from the multiplicity maxima, that the crime instance in question is somehow active, rather than historical and so have not used the role name “investigates” or “investigated” assuming “investigating” instead. I have further assumed that the potentially several officers associated with a crime are the officers who have been assigned to the crime (rather than, say, credited with solving it).

Question 6.8

Write a few paragraphs on why the many-to-many relationship is problematical and the ways in which we can try to avoid it.

[All the information was in the text, so this is test of recollection and understanding. The salient points were:

  • Difficult to implement
  • Frequently it’s indicative of model sloppiness masking better modeling arrangements, such as a missing entity “in the middle” or a necessary pair of associations. The latter possibility often also deals with another troublesome model denizen — the bidirectional relationship — when a sloppy, bidirectional many-to-many is replaced with a pair of one-to-many associations in complementary directions.
  • Probably relevant would be a comment on the historical genesis of this problem: relational database developers (reasonably) not needing to care about relationships as much as object-oriented designers and programmers need to care.

JD]

Question 6.9

The text gave an example of resolving an apparent many-to-many association between Patient and Doctor. Here, in Figure 6.46,

figure 6_46

we would seem to have a similar problem. How do we simplify this one in a similar fashion? (Hint one: the solution isn’t quite so easy as adding Visit to Patient and Doctor in Figure 6.28. Hint two: once isn’t enough.)

Is there anything missing? Is a customer directly associated with products or is something else involved? A customer places orders for products. Would Order exhibit identity? Would it be appropriate to model Order as an entity? Yes and yes.

figure 6_46a

However, we are still left with a many-to-many relationships. Is there some good and correct entity still missing? We could not adequately characterize an order with attributes that could be straightforwardly measured. There will be an open number of items being ordered. The order needs to be in a one-to-many association relationship with what is traditionally called an Order Line in a sales order processing system. With Order and Order Line present we have a simpler, a more easily implementable model, and an entirely natural model.

figure 6_46b

[There’s one more consideration. I’ve used the pair of role names “orders” and “ordered by”. The text advised against automatically inverting the grammar of the role name at one end of an association, in order to obtain the role name at the other end. The suggestion was think carefully about whether there really is a perception, a characterization; and if convinced that there was, to try to come up with a better name. Well I was convinced that there would be characterization in that direction in a typical sales order, I tried some alternative, all sounded artificial and unnatural; so I decided that this was one of those occasions when “xyzed by” was allowed as the most appropriate and correct name. If you have a better pair of names, however, all suggestions are welcome. JD]

Modeling and diagrams

Question 6.11

Think about the association and aggregation relationships that you would choose to model between the entities from your earlier answer to Exercise 6.3. Depict your choices in a UML structure diagram. Include high-quality role names at one or both ends and include multiplicities at both ends. Be clear as to how you intend to decide on association versus aggregation.

Diagram 1

strept core

Diagram 2

strept defaults

With existence-dependence as our bottom-line distinction between aggregation and association, I have no aggregation relationships; although I could still be persuaded that Faculty and Department were in an aggregation relationship, like this:

strept core b

[As usual, when one starts modeling associations, inadequacies in the first-draft entity names surface. You’ll see that several names have been sharpened. JD]

[There is not enough detail available to make definitive decisions about the exact nature of the roles. I have put in an illustrative and reasonable mixture of single-ended and double-ended arrangements. Lecturers could add more contextual description added and ask for more definitive decisions on the roles. JD]

[One early draft followed the text a little too closely and had Department -> Faculty -> Course -> Module. This wasn’t totally accurate and left at least one many-to-many, like this:

strept core a

It is also necessary to choose between Department -> Course Presentation -> Module Presentation (thus implying Department -> Module Presentation) or Department -> Module Presentation -> Course Presentation (thus implying Department -> Course Presentation). Asking whether a Department is characterized more by the courses it’s responsible for or by the modules it’s responsible for, led me to the arrangement given first.

Other many-to-many associations remain. I think the book’s point about correct granularity certainly applies here. Between Enrolled Student and Course Presentation, for example, I would probably end up quite happy to have an “Enrollment” or “Choice” entity between them. As ever, it’s better to find something reasonable at analysis time than to have an arbitrary design-time invention of an intersection object. JD]

[Perhaps one of the most challenging things to model is the default student, default module and default course. It seems hopelessly inelegant to store a whole heap of attributes in the department or the faculty.

Would there be entity sets like Default Student, Default Course, etc., distinct from the ordinary Student, Course, etc., associated with the Faculty and Departments, and whose attributes corresponded to Student, Course, etc. attributes for which defaults were held? Firstly one has to worry about the volatility of the set of attributes that would have default values. Secondly one starts to worry about pairs of entity boxes with common attributes subsets where the commonality certainly isn’t just coincidence; one wants to do some factoring.

One then asks oneself if there isn’t just an instance of the Student etc. entity that is conceptual rather than physical, and that holds the values of those attributes for which the Departments, etc. has defaults. The problem with doing that is the big difference between the hundreds of “real” instances and the handful of “fake” instances. We wouldn’t want the “fake” instances to appear in any future reports, for example. In an early version, I tried using an {XOR} constraint, like this:

strept default b

but that’s going to become unworkable as soon as there is more than one “normal” relationship. It would be necessary to change over to putting (OCL) constraints all over the place in order to stop the fake instances participating in associations which could form the basis of reports, etc.

My preferred solution so far, is to use the supertypes and subtypes you saw. There are no differences in attributes between Default Student and Enrolled Student, for example, since any attribute might have default values at some point or other; so all the Student attributes would be defined in the Student supertype. The differentiation is in the relationships. Only the “real students” participate in the “normal “relationships.

If we were to choose not to use subtypes, preferring a distinguished 1..1 “default” association with another instance of Student, etc., it might be an idea to draw more attention to the default instance and actually make it one of those rare times when we represent an instance iconically,with a box, in an analysis model, like this:
.

strept default c

Is the Notional Student really there in the subject matter? Or is it an invention too far? I think they are there: a department has a notion of a default student; and it’s a real notion; and it’s just like the real thing, except it isn’t the real thing. We can’t complain that a Notional Student doesn’t have a physical presence, because neither does a Department, nor a Debt nor a Risk, etc.

Should a supertype be generalized out of the Faculty and the Department? Some design disciplines (e.g. structured design, 1970s, Stevens, Myers, Constantine) taught us to consider removing lattice associations like those between the Faculty and the Department, and the Student, Module and Course; but I would say we shouldn’t. In the analysis the needs of diagram layout shouldn’t encourage such artificiality as a “Default Holder”. And in the design I would want evidence of enough common implementation worth factoring out, such that the factoring benefits clearly outweighed the fragile superclass drawbacks.

While my initial brainstorm was one big (whiteboard and Post-it™) diagram, it’s size and topology quickly dictated that it become at least two diagrams.

This would be (another) example of the generalization relationships offering less direct implementation clues than, say, association or aggregation. Although it seems a reasonably elegant model of the subject matter, it probably doesn’t suggest a reasonable implementation. It’s unlikely that one would complicate a Student class to the degree that subclassing it would, just to get some default values for it’s attributes. I’m certain that my designers will invent much more sensible and clever ways to achieve the result. JD]

[If you used “Course Presentation” and “Module Presentation” in a similar way to mine, you may have generalized a Presentation supertype. I probably will as well, but I think I’ll leave it noted as a probably future enhancement until I’m a bit more certain and a couple of my peers have helped me review it. JD]

Question 6.12

In ALICE, the restaurant example we worked through earlier, you may have wondered about the restriction that a booking could only be for a single table. Extend the model to indicate that a booking might occupy more than one table.

There are several possibilities. The first thing I (and several students) considered was changing over to booking virtual tables that were made up of physical tables. There are all sorts of fascinating possibilities, such as these beginnings:

alice silly tables

but this kind of thing seems to fail on at least two analysis counts – it’s not necessary and it doesn’t fit with people’s natural perception — and on one (unfair and only guessed at) count – it’s probably unworkable. Let me explain the perception objection in more detail. In the book I mentioned my test of imagining myself leading the training session where I’m teaching the restaurant staff to use the new system, and imagining how I would explain any interface manifestations of such a model. Whether I couch it in terms of super tables or virtual tables, all I can picture are blank and puzzled looks. While the designers may well decide at some future point to use the notion of a super table or a virtual table, I don’t feel that such a thing should be in the subject matter model.

When I talked to some subject matter experts, their picture was that if you had a booking you wanted to accommodate, and it was too big for any available tables, you would allocate it to a group of tables. Their mental picture was that “The Jones’ booking for 2100 next Thursday is allocated to tables 3 and 4”. “Ah,” said I, “Don’t you have to have some special way of referring to such a group?” (You have virtual tables really, don’t you?) “No,” I was told, “you can pick any constituent table’s number and use that to refer to the group. No-one’s idiot enough to get confused if told to take the Borsch to table 3, and find that table 3 is pushed up next to table 4.”

So my next inclination is to change from a booking being accepted by just one table, to a booking potentially being accepted by more than one table.

We take a booking instance and find that most of the time it’s allocated to one table; but sometimes we find that an accepted booking instance is allocated to more than one table instance. (Notice how you must reason on an instance basis; not a set/class basis.) And we take a table instance, wondering how it will be spending the next few hours or days, and we continue to see it in association with several bookings that it has accepted. We (analysts, not object instances) could follow a table to an accepted booking and follow that booking back to its table instance(s) to see if it was a large booking and which other table instances, if any, were involved.

alice seating 01

[Supplementary exercise: why did I make the qualification, “We (analysts, not object instances) …” just now? JD]

Have we got a bidirectional many-to-many association? I think we have. There is mutual characterization, which was the book’s suggested test.

[If we picture the links among some sample instances (those tuples that are now back at the heart of the semantics of associations, i.e. links are lines, not branches and not starbursts) we might have this:

association nets 02

And if we picture that implemented for full bidirectionality with typical collection objects in a typical language (i.e. typical language link implementations can branch), we’d have pointers like this:

association nets 03

and if a pointer got lost and the following came to pass:

association nets 04

then the system would be in an incorrect state. JD]

Would we check, and check again, that we hadn’t overlooked some valid subject matter element that would simplify away the bidirectional many-to-many? Yes, we would. They are simply too troublesome to get a consensus interpretation in analysis models, and to implement. Have we overlooked something? I considered an allocation but found it too artificial for an analysis model. I tried table group; it’s not all that artificial and I nearly went for it; but in the final analysis I found it to a sufficiently unusual way of looking at the subject matter that I didn’t go for it in the final analysis.

Question 6.13

The model developed for ALICE – the restaurant example we worked through earlier – didn’t take account of departments. In a large restaurant, the kitchen is divided up into departments. How would you modify the model to include them?

Having investigated whether “Menu Section” was sufficient, wondering whether it inevitably predicted the kitchen department, and coming to the conclusion that it did not, because a dish that was a starter according to the menu could actually be a specialty of the restaurant and thus not prepared in the starters department but in the main department by Anton himself, another association was added between the Dish entity and a Department entity:

alice eating deparment mod

Chapter 7

Chapter 7

Question 7.1

You are reviewing a model from the POLLY hotel system development last mentioned in Exercise 5.7. The modeler has UML generalization relationships (hollow, triangle arrowhead) pointing from:

  • Hotel Room to Property, and Conference Room to Property
  • En-suite Bathroom to Hotel Room
  • Bed to Mattress
  • Furniture to Asset, and Fitting (like a trouser press) to Asset

Say which of those you agree are generalization and which are not, and why. Note any assumptions you have made.

[The first printing of the first edition had an incorrectly duplicated entry. JD]

It was mentioned on page 20 that hotel software subsystems concern themselves with repair. If it is assumed that the meaning of “Property” here is “something that requires upkeep, maintenance and repair”, in other words “Property” is almost being used as a synonym for “Asset”, then the Hotel Room and the Conference Room would probably have enough in common that a generalization relationships would be correct. If, on the other hand, one assumes that “Property” means something that a realtor or estate agent would sell, then it is probably incorrect.

An “En-suite Bathroom” might be part of a “Hotel Room”, but it isn’t a kind of hotel room. This clearly fails the LSP (Liskov Substitutability Principle) and is incorrect.

The same thing applies to “Bed” and “Mattress” a bed might be associated with a mattress (although this is likely to fail another test — what I called “Butler’s Test” — in that it is unlikely to be relevant). Certainly a bed isn’t a kind of mattress.

“Furniture” and “Fitting” would both seem clearly to be kinds of “Asset” and the last one is surely correct.

Question 7.2

You are working on a part of the model for the STREPT student record system mentioned last in Exercise 6.11. Assuming you chose entities that included Student, Staff Member, Message, Address, Department, Faculty, Course, Module and Presentation, what, if any, are the possibilities for generalization relationships?

Hardly any! “Student” and “Staff” can probably be generalized. The first name I wrote down for the general type was “Person” but that is hopelessly overused and vague. After some time with a thesaurus I came up with “Scholar”. However, to generalize between “Department” and “Faculty”, for example, or between “Course”, “Module” and “Presentation”, would be a mistake because they are not in subtype/supertype relationships, again the LSP test is failed.

Question 7.7

(Difficult) Why do we insist that generalization relationships respect the principle of substitutability? I can think of at least two reasons.

We want to avoid making anything out of coincidental similarity. If we see common attributes or common relationships among entity sets (one might also use the term “entity class” or “class” here), it would be a mistake to create a supertype, to generalize, if it was mere coincidence. A future version of the model might change attributes or associations and the coincidental similarity disappear, leaving the model with a meaningless supertype. (OK, analysis models tend not to get many new versions as much as design models might, but then the same thing applies to design models as well.)

Also, thinking about design, there is even less chance that a generalization relationship in the analysis’ subject matter model will predict something useful about the design model if it is not backed by real, semantic similarity.

Finally, and again thinking about maximizing the likelihood that the analysis model will actually be useful to the designers, we note that between the class system of the design and type system of the design, it it the type system that the strategically more important. In our current languages it is the coupling that cannot be avoided. One of the unique benefits of object technology is that complicated trickery in C++, or interfaces in Java and C# can give us pure, abstract types; and thus the inevitable coupling of a variable holder to the variable’s type is as loose as we can manage with today’s know-how. In a famework, like EJB for example, the types (the interfaces) are published to, and used by, the framework users, whereas via careful design and the use of factory methods, abstract classes and concrete classes are not.

If we just wish to avail ourselves of some existing capabilities and mechanisms, experience has overwhelmingly demonstrated that the best way to do that, if at all possible, is with component object instances. If we are going to couple entire classes together via inheritance, there must be some powerful extra reason to do that. So when we insist on respecting the principle of substitutability (Liskov’s Substitutability Principle) we are saying, “If we are picking up type via some route, and if it makes sense to pick up default implementation over that same route, well OK. If we are primarily interested in implementation, then there are better ways to get it than via inheritance. So by insisting from the beginning that the PoS (or LSV) be respected, we ensure that type sharing is behind these more highly coupling relationships (more highly coupling that association and aggregation, which are inter-instance rather than inter-type relationships).

Question 7.10

Create a state machine to model the state of a normal room in a part of the POLLY hotel system that helps the front desk find rooms for new guests, helps room cleaning staff know what cleaning has to be done each day and also helps direct maintenance staff.

polly room state machine

This uses concurrent partitions to indicate that minor repairs can occur independently of whatever else is happening to the room. An alternative that exercises a couple of other UML state machine features, might be:

polly room state machine a

[Both solutions use time events. “Midnight” is an absolute time event, whereas the word “after” indicates that the other time even is an elapsed duration. JD]

[Be careful with transitions to and from group (composite) states. Personally I don’t usually give entry and exit actions to group states but if one does then they will fire. (As you will know from reading the book, I tend to avoid actions altogether and stick to protocol state machines. JD]

[I’ve shown group states along with their content. Make sure your CASE tool allows you to suppress the detail of group states, and that it allows you easily to “push” into the detail of a group state (e.g. double-click) and “pop” back up again (e.g. ESC). JD]

Question 7.12

You are planning the workflow for checking a guest out of the POLLY hotel system we have been considering in some of these exercises (Exercise 7.1 for example). You have investigated what happens at several of your example hotels. The activities on your list so far are:

  • Ensure the guest has returned the keycard.
  • Find the room account.
  • Check the phone record and add any calls that are not on the account.
  • Check for any breakfast tab that morning and amend account accordingly.
  • Ask about any mini-bar consumption last night and update room record accordingly.
  • Print out bill for guest to check and confirm.
  • Ask the guest if they enjoyed their stay.
  • Record any complaints and book any maintenance required.
  • Record the method of payment.
  • If a card has been used to pay, swipe the card for authorization.
  • If the card used for payment isn’t a chip and PIN card, get the voucher signed.
  • Print off the final copy of the bill for the guest.
  • Wish them away nicely.
  • Update the status of the room to “dirty”.

Draw an activity diagram for the workflow, paying particular attention to activities that are in dependent sequences versus activities that are independent and potentially concurrent. There are at least two styles for depicting decisions in UML activity diagrams; try more than one. Note any assumptions or amendments you have made.

polly checkout activity diagram

Chapter 8

Question 8.1

Consider the menu you would almost certainly encounter on one of your analyst’s visits to a restaurant. Is the menu part of the underlying subject matter? Is the menu part of an existing system?

The menu is an element of the existing, systematic, largely-clerical solution to the running of a restaurant; and the idea of a menu is part of the culture, the subject matter, of restaurants. So how do we treat it? We invoke the “is a menu still going to be there?” question. And we probably decide that it is. The concept of a menu is inextricably a part of the culture of eating out, at least for our first target marketplace. In fact, in some parts of our target marketplace, it is a legal requirement to display a menu at the point of entrance.

So we would treat the menu as subject matter, focusing on the ideas and concepts rather than the way it is currently printed.

[Question 8.3a / Question 8.4a

My recollection was that those last two questions were as follows (why they emerged in the first edition in a different form, is lost to the mists of redrafting time):

8.3

It is many years ago and you are doing the analysis for some accounting software that will run on a standalone PC. In an investigation of purchase accounting, you encounter such things as supplier invoices, rubber stamps that are applied to supplier invoices such that an authorizing signature can be obtained from the person who placed the order, a purchase day book where details of purchase progress are recorded, and a purchase ledger where the debts to suppliers are monitored. Would you be likely to be carrying out a systems analysis; and would you be expecting a reasonable degree of success? Record any assumptions you make.

8.4

The time is today and your world famous accounting package, whose humble beginnings were outlined in question 3, are being updated for the paperless offices of electronic data interchange. Would you be likely to be carrying out a systems analysis; and would you be expecting a reasonable degree of success? Record any assumptions you make.

The idea, of course, was to expect a fair degree of success in carrying out a systems analysis for question 3; but that by the time question 4’s epoch had been reached, the days of systems analysis, of computerization, and of systems amenable to study (clerks, rather than code that began many years ago on some PC somewhere) would be long-gone, and a subject matter analysis (ordering, authorization, purchasing, supplying, debt, payment, communication, etc.) would be required. Lecturers might like to set such questions. JD]

Chapter 9

Chapter 9

Question 9.1

You have been asked to help a systems development budgeting exercise by providing the finance department with definitions of the analysis, design and programming activities. (They are unlikely to appreciate being asked to read more than a page or so.)

The programming activity is specific to a particular programming language and provides the input necessary for making a computer correctly carry out a given task. A very important skill in a programmer is being to create exactly correct syntax. A civil engineering analogy would be a brick-layer or a carpenter. A publishing analogy would be a copy editor who ensures that the house style is being followed and that the punctuation and spelling are correct.

Design is specific only to a family or style of programming languages. The core of the design activity consists of invention and planning. It answers the questions such as “How are we going to build a solution?”, “What will be the elements of this solution?” and “How will the elements relate to each other?”

The boundary between design and programming isn’t clear-cut. A good programmer has to solve small localized problems, and to design small, localized structures. A designer must know what the programming language is capable of and know what structuring possibilities it offers.

Continuing with the publishing analogy, while a copy editor might be capable of a great novel, and while the copy editor will write suggested, replacement sentences and occasionally write suggested, replacement paragraphs, it is the novellist who plots and structures the novel. And while a novellist might be capable of writing correct English or whatever, they typically will not be overly concerned with “whilst” versus “while” and “towards” versus “toward”.

Continuing with the civil engineering analogy, the counterpart of our designer would be the consulting engineer, Ove Arup being one famous example.

The analysis activity is an investigative, factual or definitive activity; in contrast with the more speculative nature of design. Analysis could be independent of the programming language, although it is usually wise to deliver the analysis findings in a form that is reasonably compatible with the intended implementation technology. Analysis chooses, assembles, formalizes, abstracts and presents inputs to the design. It might be the analysis of a current system or it might be the analysis of the subject area or context of the system-to-be. Before designing a new kind of vacuum cleaner, it would be sensible to analyze the nature of carpets, upholstery, dirt and humans.

Finishing the civil engineering analogy (the publishing analogy having been stretched beyond breaking point), the analyst’s counterpart would be found within the architect, a Norman Foster if you like. The boundaries are not quite the same, however. A civil engineering architect will carry out some of what we are terming design, especially towards the end of the architecture phase. And in software systems development there is much more analysis that needs to be done. This is because there is a greater range of problems that a computer can solve, compared with the problems that a new building can solve.

Some years ago, one of the most respected researchers into software economics (Barry Boehm) discovered that successful projects spent 65% of their time in analysis and design, 15% in programming, and 25% of their time in testing. As platforms have become more powerful over the ensuing years, and as computing solutions have become ever more diverse, the percentage for analysis and design has probably increased. I note that your request for definitions didn’t mention testing. I assume that you are budgeting for that separately.

Chapter 11

Question 11.1

This book has made something of a fuss about the distinction between developing systems with an object-oriented approach rather than a class-oriented approach, whenever possible. Summarize, as succinctly as you can, what you see that as meaning. Picture that you are writing a developers’ handbook for your team and that this will form a few paragraphs therein.

The aim of an object-oriented development activity should be to ensure that the right objects are available to the right objects at the right time and that they are providing the right services by accepting the right messages. Classes are a means to that end in most languages. The class mechanism tends to vary from language to language; indeed, some languages don’t really have them. A development driven by a quest for the right objects will thus be a little more language-independent than a development driven by classes.

The input available to a designer — an object-oriented analysis — tends to suggest object instances rather than classes, so trying too early to figure out the classes that are needed means that the available evidence isn’t being used or is being used inappropriately.

It’s more difficult to design classes than objects or object types (certainly if we are obeying the prime directive, and keeping all our instance variables private). Classes have extra considerations; their factoring and their constructors, for example. Despite what Dijkstra might have said, the best objects are often designed anthropomorphically or metaphorically; it’s easier for us human developers to see things with an object orientation than it is with a class orientation.

Objects can be “bigger” than classes. By thinking about objects first and classes second, we can satisfy two goals in a neat way. We can get the right objects in an intuitive way, and without worrying about their size or complexity metrics. You see, we won’t be maintaining objects; we will be maintaining classes; it’s classes whose size and complexity metrics are important; but we can worry about that when we’ve got the right objects; and we can improve things by factoring out component objects, private and protected (C++ sense) methods and superclasses.

The practical upshot of this is that we shouldn’t begin the design activity by staring at class structure diagrams. Instead, we should begin design by carrying out exercises like CRC, and by drawing sequence diagrams as well as structure diagrams. And those structure diagrams should aim, initially, to depict object types rather than classes.

Only when the right objects are becoming clear to a designer and a design, does the evidence start to exist as to what classes should be developed.

[When one looks back at the origins of OOA and OOD, one can see that some of our early thoughts, about the criteria to be used, only work if we apply them to objects; and then follow that up with extra, possibly more recent, considerations about good, and maintainable, classes. JD]

Question 11.3

If you can’t find enough colleagues for the bigger CRC exercises, here is another exercise where you stand more chance of getting something out of it if you’re on your own. First, put your sponsor hat on and sketch out a use case scenario for a typical printing of a menu. You will probably need to re-read the requirements in Figure 5.4, on page 84. Remind yourself also of the subject matter model concerning this area, as shown in Figure 7.12, on page 181. Carry out a CRC session to enact your menu printing use case scenario, using those subject matter entities as an initial guide. Record the types, the messages they take responsibility for and a sequence diagram showing their interactions (collaborations).

If you are doing this on your own, I can’t give you much help on developing the necessary split personality other than visualization. Before deciding if you as menu, as menu section or as dish, etc. would take a responsibility, visualize the menu, the menu section, etc. If you are a dish, remember that we decided a dish was the concept that a serving realized.

[Warning: this exercise takes a long time to do properly; longer than I estimated when I put the exercise into the book. A regular CRC session, with several experienced players could expect to take a couple of hours. One one’s own, and with limited experience, one can multiply that fivefold or even tenfold. My solution might look enormously long, but that’s because I’ve included a transcript of the CRC session. JD]

[I think that one of the most typical scenarios would be taking an existing menu — probably yesterday’s or last week’s — and replacing one dish by another, prior to printing. Lecturers and tutors might want to give more guidance, when setting the exercise, as to the particular scenario. JD]

Name: Printing a menu created by modification

Scope: ALICE::seating/eating

Level: Primary task

Typical actor: Non-novice restaurant staff member

Stakeholder-interest: Owner/manager – maximize fame and profit; Staff – quick, easy and foolproof menu creation

Precondition(s): The dishes to be used are already registered with the system

Minimal guarantees: No existing menus are changed; all menus registered with the system are consistent and valid

Success guarantees: New menu registered; said menu available for formatting, printing, etc.

Initiating event: User elects to prepare a menu for printing

Output(s): Sequential-character-based representation of new menu

State change(s): system registers details of a new menu

Storyboard:
User indicates a date to the system.
System portrays the menu or menus associated with the indicated date.
User selects a particular menu.
System portrays the selected menu for recognition and confirmation.
User confirms that the selected menu is the menu being sought.
System lists portrayals of the items offered by the selected menu.
User indicates a selected dish.
System portrays the selected dish for recognition and confirmation.
User requests the removal of the selected dish from the menu-under-construction.
User requests that all available dishes be listed.
System lists portrayals of the available dishes.
User indicates their selected dish.
System portrays the selected dish for recognition and possible modification.
User modifies price of dish.
User indicates that selected dish be added to the selected menu.
System lists menu sections and requests that one be chosen.
User selects a section — the “main courses” section, for example.
User requests that menu-under-construction be output.
System list template/format/form possibilities.
User chooses, for example, “Festival” template / “XML” format / file.
System prepares output and presents details of where the file is to be found.
User indicates desire to exit.
System requests fate of menu-under-construction.
User indicates that menu will be used tonight (rather than abandoned or saved as draft).
System records menu’s fate.

[This is just an example. The respondent, with the sponsor hat on, may detail a different scenario. What we are looking for is a sensible use case description with good words and as little ambiguity as possible. JD]

[The book wasn’t trying to be a book about requirements. That may well end up an entire book in its own right. The book didn’t go into detail about extra or alternative detail for use cases. Your study may well have led you to, for example, Cockburn’s suggestions for use case content, in which case you may have had some of the extra detail above. If you just had initiating event, outputs, state changes and storyboard, that’ll do for now. JD]

CRC Transcript:

[I’ve done this as a transcript of a CRC; a little bit like the one in the book; here though, I haven’t given the characters names, nor have I set the scene. I’ve only occasionally put in who is talking.

As usual my personal interruptions are in square brackets.

“OK. Let’s say that there’s some kind of menu-search form on the screen able to accept a date.”

“Or a date range,” interrupts someone else.

“Able to accept a date, or date range, from the user. It gets filled in and validated.”

[Yes, GUIs and interfaces/views can and should do lexical and syntactic validation. What they should not do is semantics. The test is portability. Can we disconnect the application from the GUI? And can we disconnect the GUI from the application?]

“Then a button is pressed. We’ve often found that the button’s label gives a good clue as to the message, so what do we think the button would say? Search? Find? Let’s try ‘Find’.”

Mod: “So we’ve a message, headed from the view [GUI] to the model [application], findMenu(Date) return a menu object.”

“What about date ranges? What if there’s more than one menu because a date range was given?”

“We should send two parameters. No, whoops, that’s one parameter too many. Ah, we need a Duration or Period object. After all, one day is a period of time, isn’t it?” Someone makes a note to check if our language’s library or framework has such a thing.

“OK, using UML syntax, the message is ‘findMenu(searchPeriod: Duration ): Menu’.”

“Now, which type of instance gets the message?”

[Someone might suggest that Menu finds menus. But that won’t work. Which menu instance would take responsibility for finding other menus? And class methods (known as “statics” in Java and C++) won’t do either. Once you start doing things with class methods, you’ve drifted away from object-orientation towards class-orientation. And the former definitely works better.]

[Someone might suggest “the database”. Well, no. Once one object knows that any kind of database exists, they’ll all want to and then we’re doomed if, for example, we want to move from one persistent data technology to another; especially if it’s from a creaky or rickety technology like relational or object-relational to something more svelte like persistent objects.

In order to hide a non-relational database, and to better use an “object-oriented database”, we should ask an object to find menus, and hide the way it’s done in there (and maybe even one more level of hiding than that). So, which object?]

[Someone might suggest the Restaurant. However, while the typical statement, “Let’s make a booking at Zingarelli’s restaurant,” left me (the designer) reasonably happy that a restaurant be the first application object to receive a message in a “booking” use case scenario, I (a restaurant instance) would not be quite so happy to accept findMenu(). It seems “beneath me”; although I know enough (or enough objects that know enough), I know more than is needed in order to take responsibility for this message. I suspect that there’s another object that’s “closer” to the information. I suspect that if I took responsibility there would be delegation with no added value, i.e. buck-passing rather than real delegation.]

Our participants look at some structure diagrams (“class” diagrams), pinned to board. There seem to be no clues, however.

Everyone seems to be stymied.

“Let’s try some existing-systems analysis. How do they currently record the menu usage patterns? First possibility: they have a log book; second possiblity: they write it in the diary.”

However, Diary refuses. “Outside my character,” it says. Especially if it sees itself as the same kind of diary that was deployed in the “booking” CRC, in the book (11.11.2).

“Looks like we need a new object. Maybe we have to invent one. Or maybe they really do use a log book. We need a ‘menuLog’.”

A card is written out and a player chosen.

“MenuLog, would you take responsibility for ‘findMenu(Duration searchPeriod):Menu’?”

“Yes. It would be churlish to turn it down if that’s what I’ve been invented for. But I could be a bad idea. However, I don’t think I am a bad idea. Yes, I’ll do it. Now, if I’m a log, it seems in my nature that I would be strongly aware of the idea of a time or time period, so I would simply return the IDs of the menu instances referenced by the time period. I don’t think I have to delegate.”

“Are you sure? We shouldn’t pass up an opportunity for an object to be simpler.”

“Or more general-purpose. What if we needed several logs, and this log is just an instance of a general-purpose log class of some kind? In fact, some platforms provide generalized logging services.”

“You’re right! I could simply be a collection of log entries and I message them to divulge their menus.”

“That’s not particularly general purpose — assuming that a log entry contains a menu.”

“Why not ask it if it has a menu instance associated with it. Ah, no. That would involve a cast, and we don’t like casts.”

“Let’s try ‘turn it around’. Could we say to an entry, ‘Do you have one of these?’ passing an example instance, a menu instance in this case. The entry simply does a type comparison between the argument object and object it’s linked to, and returns it if there’s a type match, without the code ever specifically referring to the type, or doing a cast.”

[This isn’t quite good enough. At a low level the return type makes the method too specific. At a more conceptual level, we object to a method doing to jobs: “Are you linked to one of these?” and “Give me a reference to your linked object.” In a language with generics or templates, they would offer a neat solution.]

“I like it. Let’s write an ‘algorithm suggestion’ straight after the session. I think we can agree that the responsibility has been taken and that any further exploration of the delegation isn’t validating object type interfaces. Let’s move on.”

“OK. A set of menu instance references or pointers is returned to the GUI.”

“Eek. Doesn’t that mean that I (the GUI) have to start knowing an awful lot about restauranting?”

“Seems inescapable. You (the GUI) have to display enough characteristics of the menus that they can be recognized by the user.”

[The worry about too much knowledge is a good one. Within the “view” of the highest-level model-view separation, there needs to be a mini-model-view separation. What Swing (a Java view technology) calls “model-delegate”. There is a little more on the “model-view” architecture in a moment. Quite rightly, however, these people are focusing on the design of the application (the “model” of the highest-level model-view separation).]

“You’re right. I’ll have to message the menu for some things.”

“Let’s just try an example. It’ll validate a bit of the menu object type.”

“Menu, would you take responsibility for dateDeployed()?”

“Yes.”

“Fair enough. What does the use case involve next? Ah, yes. A menu is selected, portrayed and then a dish is found and removed.”

“I think the details of the portrayal will be the same kind of details as dateDeployed() just now; only more of them. Do we need to go through that?”

“Yes. No short circuiting. I mean, to truly confirm that you’ve found the menu you’re looking for, surely you (the user) will need to see some dish details.”

“Don’t we just message the menu in question to portray itself suitably for a screen presentation?”

“Yes but I can envisage such a message eventually being replicated in myriad subtly different ways for different clients’ needs. That’s a mess. The trouble is, a general toString() method isn’t necessarily going to work either; there’s no guaranteeing it’ll be suitable.” [Java and Smalltalk have a guaranteed string representation (toString and printString) of any object; but only its presence is guaranteed; what the string actually contains could be anything.]

“OK. The GUI has to send individual query messages to get the items of information that it can then assemble into a reasonable display.”

“But doesn’t that make the GUI hugely complicated and highly dependent on forbidden knowledge of the model [the application classes]?”

“Well a view has to have some knowledge of the model — just minimal knowledge. And it doesn’t have to be complicated if it’s factored into a set of objects: for example, one for the intrinsic menu stuff and another for dish stuff. Now, we shouldn’t be designing the GUI in a CRC, but I think it’s reasonable to say that it could be done with decent ‘objects’ that would each know only about their model counterpart.”

“OK. For example, then, the menu gets a message title(). Menu are you happy to accept responsibility for that?” [Menu nods.] “Do you need to collaborate?” [Menu shakes her head.]

“And, Menu, are you happy to accept responsibility for giveUsYourDishes()?” [Menu shakes her head. Her interlocutor is somewhat taken aback.]

“Hmm. Why not?”

[Menu waives a picture of a Greek lady attached to a short stick.] “Demeter.”

“You’re right, of course. That would be wrongful access of the objects inside the object I can see. What would be an acceptable message? It can’t be give me a description of your first dish, since we want a GUI [view] dish object to send its choice of query messages to a model dish object.”

“I think you’ve put your finger on it there with ‘first’. The idea of an iterator is well-established. I recall that we noted a peculiar characteristic of the menu when doing the subject matter analysis. It had hardly any attributes [intrinsic measureable properties] it was mostly who it knew rather than what it knew.”

“Aha! Menu would you accept responsibility for dishIterator()?”

“Yes I think I would.”

Mod: “So the GUI ‘menu’ knows some menu query messages, and that a menu ‘has’ dishes and can be asked for a dish iterator. We presume, because we’re not designing the GUI [which anyway is usually done by tool rather than by hand-coding] that successive dish references/pointers are passed to a GUI ‘dish’ object whose mission is portrayal of a dish. We want to know about example messages from the GUI ‘dish’ object to the model dish object instance, however, so let’s posit name() and price(). Dish, would you accept responsibility for answering a name() message.” Dish nods. “And price()?” Dish nods once more.

Menu: “I think we should follow the rules properly and ask me if I need to collaborate over my responsibility for dishIterator().” The moderator looks embarrassed.

Mod: “Quite right. Who would you like to collaborate with?”

Menu: “I’d like to collaborate with my menu sections.”

There are several “Doh!”s from around the table.

“We need to backtrack a bit. Won’t GUI.Menu need to ask our menu what sections there are and then display the menu section by section?”

“You’re right. Menu would you take responsibility for ‘what sections have you got?'”

Menu: “I think I’ll refuse on the grounds of vague return.”

“We should do what we did before. Why not ask Menu for a section iterator that returns successive section pointers …” Menu nods. “… and then GUI.Menu or GUI.Section messages sections for their names and for a dish iterator from each.” [People tend to say “dot” when qualifying names: “GUI dot Menu”. To use the UML/C++ “dot, dot, dot, dot” (::) is a little cumbersome.]

A menu section card is created. The bottle is spun. The Menu Section player is asked, “Would you take responsibility for name()?” “Yes,” says Menu Section. “Do you need to collaborate?” “No,” says Menu Section. “Would you take responsibility for dishIterator()?” “Yes.” “Do you need to collaborate?” “No.”

“So the selected menu has been portrayed, its contents have been portrayed, and now the user indicates their selection of a dish. If the GUI messages the selected dish for some information to portray for recognition, such as name(), price() and maybe describe() as well this time, Dish would you still be happy for the first two and for the third? Dish says, “Yes”.

“And now the user indicates that the selected dish is to be deleted. So where does that message go?”

“To the … Oops. We’ve missed a whole chunk of stuff here. Where do we create the new menu? The one that’s a copy of the chosen menu.”

[Many programmers [hackers] would find themselves doing all this to and fro, back and forth, in code. And the code would very soon be a complete mess. Isn’t it much better to be doing the toing and froing here?]

“OK, how does the user indicate that they want to copy the found menu and modify the copy. The use case doesn’t say? Does the whole dialog start off as a “New Menu” diaglog? Or does the system ask them if they wouldn’t rather modify a copy, at the point where they are about to change the found menu?”

“Well, as we know, the GUI design is still evolving over with Team B. And we are CRCing the application [model] classes. Is it sufficient for us just to explore who takes responsibility for copying a menu instance, for changing a menu instance, etc. We don’t have to ask exactly when those messages occur.”

“That’s true. Except for John, here, who has to draw the sequence diagram, and who will need to put that message somewhere.”

Mod: “OK. Let’s make a note that this CRC session has arbitrarily put the menu copying message at the point where the menu that we just realized had to be copied, was selected.” “Do we agree that that’s OK?” There is agreement. “And which object should perform a copy of a menu?” It is decided, quite reasonably, that the source menu object should be asked to make and return a copy of itself.

“So where were we? The user indicates that a dish that’s selected/highlighted in some way on the screen is to be removed from the menu-under-creation-by-copy-and-modification. Now, who takes responsibility for that? Menu? Menu Section?”

They glance at the structure diagrams (“class” diagrams).

“Seems like it should be Menu Section. What do you think, Menu Section? Is it your responsibility to remove a listed dish?”

Menu Section agreed and no collaboration seems to be required.

Another message comes in from the GUI requesting that the available dishes be listed, as the use case says that our user is going to pick a new dish for the menu-under-construction. Who will take responsibility for availableDishes()?

[Someone, especially in an experienced group might say, “A static (class) method of Dish.” This isn’t a good idea, however. If one is intending to be object-oriented, then functionality should be provided by object instances running methods on their own, individual state. A class method (a “static” in C++, etc.) is run by the system in C++, where a static is more like a regular (global, C, free) function rather than a member function); or run by a class in Java and Smalltalk].

Chef? Well, … it seems promising. Chef would probably agree. There are no show-stopping reasons to refuse. If you went with Chef, it should work.

Repetoire? Yes. Repetoire agrees that it’s its responsibility. [There was a repetoire object suggested by the analysis. However, it’s quite likely that many analysis effort might not have included it — initially at least. Hence going with Chef might be an alternative. On balance, I think I (the designer) prefer Repetoire. It seems a better home for “all the dishes we might offer”. Chef seems close but not quite as close.]

“OK, Repetoire, who are you going to collaborate with? Who are you going to delegate to?”

Repetoire: “It seems pretty simple to me, I message each dish for it’s name and I return … Ah, it’s not so obvious. What good is a collection of strings? GUI.Repetoire should have some choice as to which messages it uses in order to get what it wants to display. I guess it’s an iterator again.”

“I’m just a bit worried about these iterators. Can I think aloud for a moment about the validity of what we’re doing? We are considering an interface message, dishIterator(), both for a menu section and a repertoire.” (“So there’s scope for some kind of super-type similarity between these two?”) Now, it’s true that while they might not substitute for list objects [the Principle of Substitutability would say they shouldn’t carry a list type], a large part of their nature is to list dishes. And it’s been found time and time again that a flexible way to access a list without actually accessing the list is to ask the list to provide an iterator. And it would certainly enable the application-facing side of the GUI to obtain a collection of strings with which to populate some kind of screen choice list. OK. I’m happy.

[Students who are familiar neither with iterators nor model-view, should consider finding out more about both. Neither are particularly specific to object-orientation. I have, on another web site, a paper that would get you started on model-view. For iterators you could look in the design patterns world for the External Iterator pattern; or you could look in the C++ world for the STL’s (Standard Template Library) iterators; or you could look in the Java world for the Collections Framework.]

“The user indicates a chosen dish which is portrayed. We have already established some messages with which a dish could be portrayed to the user; so the GUI or whatever can do its portrayal.”

“Now we want to modify the portrayed price of the dish. The clicking and typing isn’t germane. Let’s assume we get to a point where some kind of ‘Update’ button has been pressed.”

“Who should take responsibility for price(newPrice:Money)?”

“I would have thought Dish. Dish, what do you think?”

“I’m not sure. What price am I modifying? Is it that I used to have a price, even if I’d never been used in a menu before? And now that I’m about to be used, I am learning of a more correct price? Or, if it’s the case that I’ve never been used before, am I learning my price?”

“Or maybe the price we’re talking about is the price for this appearance of this dish on this menu and that another appearance of this dish, in the future, say, might carry a different price. And maybe the system needs to be able to recall the price of a dish for any of its appearances.”

“Ah. I don’t think that’s ever occurred to us before. Maybe the price we’re talking about is a property of the menu and not the dish.”

“Yes, Menu, would you take responsibility for price(newPrice:Money)?”

“I don’t see how I can. Which dish’s price is it?”

“Hmm. We’ve encountered this many times before, if you see what I mean. Perhaps we’re missing the intersection object. What has appeared so far to be a many-to-many relationship, and thus already problematical, has encountered further problems, and only now are we being led to discover the ‘missing object/entity’ that the OOAandD course we attended went on about so much. Is it that we need an ‘Offering’ between a menu and its particular use of a dish?”

Randomization devices are deployed; a card is written out; a player gets into character; and, yes, an offer object is a righteous object and it knows the price. And perhaps a dish has a “nominal” or “suggestion” or “guide” price. An offer instance is in a many-to-one, existence-dependent (aggregation) relationship with a menu instance; and in a one-to-one relationship with a dish instance. Offer objects are nicer object to festoon with query messages delivering the details of the offer: the price, the name and the description. It is more natural that they describe the offer, rather than the dish. The dish’s interface doesn’t need to be “polluted” in any way. If the offer finds it appropriate to ask its dish then fair enough; if the offer stores or computes its answer, so be it.

[So another many-to-many relationship bites the dust. And more evidence accumulates that those who say that not only are n-ary associations a chimera and a mirage, but many-to-many associations fall into the same category, might be right.]

“Now that tonight’s new dish has been chosen, the use case says that this dish — sorry dish offering — is added to the menu-under-construction.”

“I don’t think that’s quite true. The menu sections are listed, and the user chooses one. And I’ve just had a thought. Somebody might decide to support this kind of thing with drag-drop. So the user might drop the dish offering into the menu section of their choice.”

“You’re right. Presumably we message Menu for it’s menu sections. Ah, but we’ve already established that that’s possible a moment ago. We’re determining application object type messages and this wouldn’t uncover anything further. Onwards.”

“Right, we want a message to a menu section. How about addOffering(Offering)?”

“It’s best not to include type names in message names; add(Offering).”

“Hey. I’ve just realized. I had been wondering about to type of the argument if we had been wanting to add a dish to a section; whether it would have been add(MenuItem) or add(Victual) or add(Comestible). That’s another design decision that the existence of the offer object can hide.”

“Ah! Nice.”

“OK. Menu Section would you take responsibility for add(Offering)?”

“I’m almost happy. But I think I’d like an indication of where to put it. And, on behalf of Offering, I’d like to ask where the offering came from. Who makes it?”

There is some debate. Then someone realizes that the natural perception is that one adds a dish to a section of a menu and the section then offers that dish at some price. So they revert to adding a dish to a section, with the section creating the offer object. They then move on to MenuSection’s position worry.

“How about two arguments add(Offering, position)?”

“We’d prefer one argument over two.”

“I know, I know. Menu Section has given us an iterator. Can we message the iterator to move to a place and then message it to insert a dish?”

“Let’s ask.” The moderator writes out a card, spins the bottle and passes the card to a new role-player. “You’re an iterator. Would you accept responsibility for moving to a particular place in the collection you’re iterating over?”

“Yes.”

“And would you accept responsibility for insert(T)?”

“What do you mean ‘T’?”

“Sorry, I was assuming something like C++ templates or Java generics and that an iterator would be fairly independant of what it was iterating over. ‘T’ is a traditional, formal name for an as-yet-unchosen type.”

“I see. Yes I think I would accept responsibility. But what about if I was asked to go to a non-existent position?”

“Well this use case/CRC is exploring a successful menu adaptation and print. It’s a good point, though. Why don’t we make a note of the question? Iterators are well-known; there must be some standardized answers to that kind of question.”

The use case is consulted. The time has arrived to get the menu output.

“Where does the interface send its message for the lists of possibilities as to layout, format and form?”

[At this point your author has run out of time, stops playing the roles and starts to write what he imagines is a likely answer. If you carry on playing the roles and following the CRC method as per the first part of this answer, you may well come up with a better thought out solution to the remainder of the use case than that which follows. You might drop me an email if you do.]

Various possibilities are tried for layout and format. No-one seems to want to take responsibility for format. Eventually Menu agrees that it should offer its layout possibilities, presented of course, as menu layout objects. There might, once again, be debate as to whether such functionality should be via a class [static] method, or via an ordinary instance method. While a class method might seem possible, it’s felt that an instance method could work equally well, that something might crop up in the future that would change the functionality into eventually being menu-specific, and most of all, that the general principle, that in object-oriented systems, functionality is best delivered by objects and not classes, should be followed.

When they realize that the return type is a collection of layout objects, one of which is chosen, they further realize that a layout object can take responsibility for the format, and that the format can take responsibility for the form. I.e. they ended up using a chain of “factories” — a well-tried combination of two famous design patterns: chain of responsibility and factory method [TCP/IP socket connecting and JDBC connecting in Java, for example]. The format possibilities are likely to be volatile — HTML yesterday, XML today and who knows what tomorrow — so a factory method is a pretty good idea. The form is likely to a little bit platform dependent, but they realize, that an even more well-known, classic solution to the “producer-consumer” problem would do nicely: streams. The selected form object presents the selected format object with an stream, the selected format object presents itself to the layout object as a stream — a filter stream.

Much of the describing has been covered already. It would be worrying if the final portrayal mechanisms differed significantly from those deployed so far. The layout object messages the menu to get menu-specific descriptions, and then through a “section” iterator and “offering” iterators it obtains the remaining descriptions it needs. All of the descriptions will be in terms of character streams, to which the layout object adds its own characters. If it’s a simple layout, it just adds characters like spaces, tabs and linefeeds. If it’s a cleverer kind of layout object, it adds things like RTF, HTML or XML markup. The user might then take the output (a file typically) and pretty it up even futher, in a DTP (desktop publishing) package for example; ALICE has finished its part of the job, though.

[The separation of responsibilities might strike some as being over-the-top. However, it is much more amenable to extension. For example, one could easily create a new kind of menu layout object that used a JSP page as its form object. The JSP page could have beans that send messages to the other objects.]

Sequence Diagrams:

[I’ve broken the sequence into two diagrams, the second simply following on from the first. JD]

Question 11.5

Draw up a UML sequence diagram for the section of the case study’s CRC session from where a suitable zone starts to message its tables on page 306, to where the diary has replied that there’s no clash on page 309.

Chapter 12

Question 12.3

Produce a revised version of the sequence diagram from Exercise 11.5 in which the interface type Appointment is used appropriately, loosening the coupling.

Question 12.4

In the section on bidirectional many-to-many associations (Figure 12.42), there was a Crime and Suspect example where an artificial intersection object was chosen to help us out. From your, theoretical of course, knowledge of the subject matter, how many better objects can you come up with?

  • Participation
  • Collusion
  • Perpetration

Question 12.6

“A newcomer to object-oriented programming might confuse possession with access when considering inheritance of instance variables.” Discuss.

When first encountering the concepts of inheritance (and there is certainly more than one concept to be grasped and, hence this discussion, tricky to grasp properly), one can form the incorrect impression that there will be an object of the subclass (derived class) somehow linked to an instance of the superclass (base class). That’s not how it works though. Instead of two instances being linked, it is the classes that are linked, and together they produce a single object instance. (Indeed, that’s two of the problems with inheritance: object encapsulation is removed rather than strengthened; and inheritance must affect the entire set of instances and is a compile time choice rather than a run-time, perhaps pluggable, choice.) So, if there is just one instance, and it’s an instance that is likely to be seen as a subclass instance, one must ensure that one is clear as to what state, what instance variables, it will have available to it.

One must realize that, under the normal polymorphic kind of inheritance (public inheritance in C++), an object might receive a message that binds to a method that is an inherited method, and the said inherited method is very likely to expect and depend of the presence of superclass instance variables that must therefore have also been inherited as well.

If the inheritance mechanism required that a class using it made superclass instance variables automatically public, we would surely have stopped using inheritance altogether, many years ago. No; we must simply require that superclass instance variables are always present in subclass instances, whatever their access categories.

So what does private mean for an inherited instance variable? It means that it can only be accessed by superclass methods. Inherited variables are available only to inherited code. So some class encapsulation is at least kept, even if instance encapsulation (which in contrast, composition-delegation preserves) is lost.

Question 12.x

Why would I hope that any modern object-oriented programming style guide would discuss the correct use of abstract and final (or sealed) keywords in class definitions? And what do you think it would say?

[This exercise was inexplicably omitted in the first printing of the first edition. JD]

Today’s languages, assuming they even have these keywords, are a bit timid as far as using them in sensible default ways. So it’s important that style guides discuss the issues.

Textbooks frequently get this area wrong and don’t use the keywords.

Not all languages have all the necessary mechanisms provided via keywords (C++ for example), so it’s important to discuss how to get the same effect via idioms and patterns.

As discussed in the answer to question 12.8, it’s very important that base classes aren’t instantiated. Correctly doing two jobs (providing default implementation and transmitting type) with one relationship is difficult enough; doing three (adding instantiation) is close to impossible. So if a language has the abstract keyword (or its equivalent) to prevent a class from being instantiated, even when it has no abstract methods, then that keyword should be the default for all superclasses.

It’s also very important that concrete classes don’t become superclasses later in their careers. Otherwise some perfectly happy class is going to become a fragile superclass; and you will almost certainly have to carry on instantiating it, and thus break the rule about instantiating superclasses. So if a language has the final keyword (or its equivalent) to prevent a class from being subclassed, then that keyword should be the default for all concrete classes.

Question 12.10

Between Figure 12.43 and Figure 12.47 the name Officer changed to the implementation class name UniformedOfficer. Revise and describe the general principle being illustrated here.

Type names should be as specific as they need to be, and no more specific than that; concrete class names shouldn’t intrude into the space for future concrete class names.

When some piece of moderately strongly typed code declares a parameter, a return or a variable, it should be saying something like, “I need, in this resource here, something that is no less than an Asset, and no more than an Asset.” To have used InvoicedCustomerThatOwesMeMoney when only Asset was required is closing the door to future flexibility. One is only programming in the present tense, and as Larry Wall I think said, one should program in the future tense.

When one is fabricating a concrete class, on the other hand, one is coming up with just one way of implementing a type. There will be other ways. If one uses up the the name Officer, one will regret that when one comes up with plain-clothes officer and realizes that the original officer was a UniformedOfficer. Concrete classes should have narrow focused names that leave room for other ways of making objects in the future.

Question 12.11

(Difficult) Speculate as to:
a) why I didn’t use Crime and Location for the example of a directed characterizing inter-instance (“association”) relationship in Figure 12.37. (Hint: this continues the theme of the previous exercise.)

Because I would have had an association emerging from a generally named thing that was probably an interface; and associations should not emerge from interfaces (interfaces or pABCs).

b) the purpose that the :name labels are serving in Figure 12.39 and why I would have felt uncomfortably about an example that omitted them.

This is almost same thing: associations typed with class names, especially concrete class names are not very flexible.

Question 12.13

In the discussion of Figure 12.93, I initially wrote, “Perhaps an insightful factoring scheme can obviate storing the name instance variable in so many places.” Why was that silly; why did I rephrase it, “Perhaps an insightful factoring scheme can obviate defining the name instance variable in so many places?”

It wouldn’t make any difference as to whether one defined an instance variable in a subclass or its superclass; subclass instances would always store, i.e. possess, just one copy of an instance variable, whether it was defined in the subclass or in the subclass’ superclass.

[Languages vary as to what would happen if one did something completely silly by defining the same instance variable in both a subclass and its superclass. JD]