This paper describes some of the patterns that occur in my sophomore-level Object-Oriented Programming course. You can find nearly all of these patterns documented in the patterns literature, though not always written at a level or in a form suitable for my students.
I teach a course 810:053, Object-Oriented Programming, using Java. Students must complete our CS1/CS2 sequence before enrolling in 053, though currently nothing prevents students from waiting to take this course until much later. The goals of the course include having our students learn (1) how to do object-oriented design and programming and (2) a second programming language. In 053, I use Tim Budd's Understanding Object-Oriented Programming using Java as the primary text, with Arnold and Gosling's The Java Programming Language as a required reference.
Our CS1 and CS2 courses are taught in a fairly traditional way, using an Ada'83 subset of Ada'95 to introduce students to procedural programming, data abstraction, and encapsulation. Thus, I should not have to devote much, if any, time at all to matters of common syntax or to the mechanics of selection and repetition constructs. Students' understanding of data abstraction and encapsulation are weaker than I might otherwise hope.
I am teaching 053 for only the second time this semester, and so my ideas about the course and about the patterns therein are still inchoate. As a result, this paper is truly a work in progress.
The following time line describes roughly the order in which we cover topics in 053 and roughly when students encounter which patterns.
We introduce the course, Java, and object-oriented design
We first get to "real" OOP, and these patterns arise immediately:
I noticed the Java idiom Application Class.
Students have now seen enough inheritance to work with:
As we explore inheritance in greater detail, I expose students to:
Substitution recurs throughout the semester, especially when we delve into the idea of polymorphism (9th week forward) and when we work through a case study on the design of a payroll system (13th week).
To give you an idea of what my students, I offer two sets of lecture slides that I used in class this semester. They will seem a bit incomplete, since we fill in many blanks during lecture, but should give you an idea of what we do:
Remember that you are seeing these warts and all. Please be kind, and I welcome constructive suggestions!
I introduce Decorator as a natural extension of Substitution. Here is the set of lecture notes that I used this semester (beginning with a page of notes that I made to myself after the session on how to improve the session for next semester).
We study the Java AWT and Java's stream class hierarchy as rich sources of polymorphism. In these packages, we encounter the following patterns for the first time:
in addition to most of the others we have discussed previously.
We cover Budd's chapter on design patterns and do a backward canvass for the patterns we have encountered earlier in the semester. To motivate the idea of design patterns more generally, I work through examples that demonstrate these patterns in Java:
I also try to relate the State pattern to substitution, though the ideas behind substitution are more important than the ideas behind state transitions.
Last semester, I asked students to implements a simple four-function calculator in Java as a programming assignment. When we refactored a typical student solution, I tried to introduce the Command pattern. But I need to do a better job this time around...
We cover work through a payroll system case study, and we refactor student solutions to a simple file reader. Both are ripe with recurrences of patterns the students have seen, though I did not do as well as I might have last time on the file reader.
Of course, I also emphasize a number of patterns not specific to OOP but more general to the task of writing Simply Understood Code, such as Intention Revealing Name and Role Suggesting Temporary Variable Name. Thumbnail sketches of these patterns appear in the External Patterns section at the end of the paper.
Use an instance of a class, not a procedural "main" program.
Example: DieTester
See Kent's pattern of the same name.
See Kent's pattern of the same name.
See Syntax Procedure for a functional equivalent.
See Kent's Getting Method and Setting Method patterns.
See pattern of the same name by Dick Gabriel.
Is this really a pattern?
You are writing an OO program in a hybrid language such as C++ or Java.
Where do you put the functionality that starts the program?
In Java, you can put your main() method in any one of the classes of your application. But this allows the main() method to access private data and methods in the class.
Therefore, write a separate application class considting of a single main() method.
When your application is intended as a test of one or more classes, you can now be certain that your class works without clients needing to break encapsulation.
Example: MouseListener interface -- MouseAdapter class -- a limited mouse listener
You are writing a class. You expect the class to be subclassed later.
How do you provide future subclasses access to your class' instance variables?
A subclass will inherit your class' instance variables; they become part of the subclass' state. You would like to allow the subclass to manipulate its inherited instance variables in much the same way it manipulates its locally-defined instance variables.
The simplest solution is to make the instance variables protected. In this way, the inherited variables are accessible to the subclass but not accessible to client code. But if subclass code directly accesses inherited variables, then it becomes tightly couplied to the representation of the superclass. A change to the superclass can affect the subclass.
(You would like to preserve the encapsulation of your class...)
Therefore, make all of the class' instance variables private but provide protected access methods for use by future subclasses. (Link to Access Method pattern above.)
(For example...?)
(Resulting Context?)
See idea behind Dwight's pattern of the same name in his Foundation Patterns paper.
When objects need to behave different ways, create a small hierarchy of roles that shares an interface, and then create an IV in the class typed to the interface/superclass.
Examples: payroll methods and employee classifications in the payroll case study
See the idea in Bobby Woolf's Object Recursion paper.
Example: cloning in Java
Nice use of delegation...
See GoF pattern of the same name.
Example: physical and virtual streams in Java
See GoF pattern of the same name.
Example: frames holding frames in the Java AWT
See GoF pattern of the same name.
Example: frames and layout managers
See GoF pattern of the same name.
Example: use of Enumerations in Java
See GoF pattern of the same name.
Example: creation of an Enumeration for an vector or hash table
See GoF pattern of the same name.
Related to Substitution.
Example: the roles played by a video in a video store, over time.
See GoF pattern of the same name.
Example: the functionality for operation buttons on a calculator
The following patterns are not a part of Roundabout but are referred to by one or more of its patterns. Links to on-line versions of the patterns are provided where available.
Similar concepts in other programming styles
Teaching undergraduates using patterns
My colleagues at the 1998 Hot Topic on Elementary Patterns provided plenty of ideas and valuable discussion: Owen Astrachan, Joe Bergin, Robert Duvall, Ed Epp, and Rick Mercer. I also thank the many members of the patterns community who have encouraged us to write this sort of pattern, especially Ken Auer and Kent Beck.
http://c2.com/cgi/wiki?SimplyUnderstoodCode
".