Frogs design

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(The Redesign: step one: Did some of the things discussed in the second lecture.)
m
Line 1: Line 1:
 
'''An OO model of frogs.''' This beautiful design appeared in the 2004 427 exam.
 
'''An OO model of frogs.''' This beautiful design appeared in the 2004 427 exam.
  
[[image:frogs.gif|900px]]
+
[[image:frogs.gif]]
  
 
== Design notes ==
 
== Design notes ==

Revision as of 06:59, 31 July 2008

An OO model of frogs. This beautiful design appeared in the 2004 427 exam.

Frogs.gif

Contents

Design notes

  • This design models the lifecycles of Frogs.
  • A Frog begins life as an Egg, grows into a Tadpole and then an AdultFrog.
  • A FrogBrain belongs to a Frog and manages its behaviour.
  • There is one Biologist, Igor, who sometimes moves Frogs around. Igor has been known to fry their legs in white wine.
  • Toads don’t have the same lifecycle as Frogs, but they look and act a lot like Frogs.
  • Toads eat AdultFrogs.

Broken heuristics

  • Avoid becomes - Frog phases of life are modeled by inheritance: Egg Tadpole, AdultFrog.
  • Beware type switches - the phase variable in Frog is based on the type of an object (Frog).
  • Beware value switches - the swim() method in Tadpole differs in behavior based on the value of an attribute (type).
  • Avoid no-op overrides ("Design by Contract") - the derived class Egg overrides the base class's hop() and swim() methods with methods which does nothing.
  • One key abstraction - the Move interface contains more than one key abstraction. It contains methods to move such as hop() and swim(), but it also contains a display() method which is a separate key abstraction.

"Feels Bad"

  • Toad is a subclass of AdultFrog.
  • FrogBrain contains an array of Egg.
Why do these things feel bad? --Wal

Go export yourself

Should a Frog be able to export itself?

Frog.jpg

Our discussion of this was quite polarized. Some thought the current "frog.exportXML()" arrangement was consistent with the Keep related data and behaviour together heuristic, seemed the most intuitive way of calling the method, and thus fine how it was. Others expressed concern that having many classes with an "exportXML" method was not elegant, and would result in unnecessary repetition. Also, such methods violate the principles of One key abstraction, Separation of concerns, and the Single Responsibility Principle.

Criticism is of little value unless a better solution can be proposed. Hence the latter camp suggested the Visitor pattern. Under their proposal, XML exporting methods would be grouped in an XMLVisitor class. To export XML, the class would be used in this form:

frog.accept(xmlVisitor)

This is certainly a viable solution, and has the advantage of grouping all XML export methods within a single convenient class.

At this point we noted an intrinsic conflict between the design maxims. Separation of concerns seems to strongly contradict the idea that we must keep related data and behaviour together. We must then ask what we mean by "related", and what exactly defines a "concern".

My view was that XML-exporting methods for various objects are related in a technical sense (they work with the same format) but not in an object-oriented sense (they export totally different objects). The raison d'etre of object-oriented design is to group parts of a program on the basis of their real-world and logical relationships, rather than their technical relationships. Consequently, we ought to group a method that exports frogs in XML with frog-related program components, rather than XML-related program components. Thus the first solution seems more sensible to me.

Duplication of XML-exporting code can then be avoided by using an XMLExporter class that frog.exportXML and other exportXML methods can use behind the scenes within the implementation of that method.

--Robert 06:18, 31 July 2008 (UTC)

The Redesign: step one

While it is far from ideal here is a step towards a better design (In my opinion).

What have I done?

I have addressed the violated heuristic Beware type switches and Avoid becomes by replacing the storage of the phase in the Frog class with a State design pattern using the Frog as the context and Egg, Tadpole, AdultFrog as concrete states for the adstract state FrogLifePhase'
Click to enlarge

' While it still encourages the use of no-op's the FrogLifePhase now implements the interface Move

A new Abstract class Amphibian has been introduced to better represent the relationship between Frog and Toad.

A better place for the list of all frogs to be kept might be in the Biologist class so i thave moved it there from the Toad class.

Some things may just not make sense now like keeping a list of all the eggs when it is probable that there will only be one instance of the Egg class shaired by all Frog classes.

Personal tools