Session 4

Refactoring Programs and Design

Computer Science II
Object-Oriented Programming

Cool Coder Ad

Recently, Dr. Schafer posted this cool coder job ad on his office door. I get the geek points, but not the extra credit. Fortunately, I have a Java compiler to help me satisfy my curiosity:

    public class CoolCoderAd
        public static void main( String[] args )
            char[] msg = {78,111,119,32,72,105,114,105,110,103};
            System.out.println( msg );

Develop the habit of answering your own questions by writing a program, whenever possible. This gets you answers sooner rather than later, but it also gives you more practice with your tools and Java. And this mindset is part of what it means to be a scientist.

(By the way, I'm pretty sure that the job ad was actually in C, not Java, but the two share this syntactic feature.)

Implementing a New Feature in Our Bowling Game

Now that we've successfully implemented scoring of a bowling game, let's add the next natural feature of scoring.

New Requirement: Print the Scoresheet

Let's add to BowlingGame the ability to print out the results of the game, in a form similar to what real bowlers use.

A bowling scoresheet looks something like this:

a blank scoresheet for bowling

The small boxes in the top row are for the number of balls knocked down with individual rolls. By convention... [X and /].

A bowling scoresheet looks something like this:

a completed scoresheet for bowling

(I used a Java program to verify my score!)

How easy will this be for us to add this feature to BowlingGame?

Preparing to Add the Feature

We are in conflict with the Principle of Continuity. Bowlers talk about frames, as we did when writing code to score the game, but our program doesn't talk about frames. Up to now that was okay, as one can keep score without knowing anything about frames, but now we need to modify our program to to talk about them, too.

Last time, we cleaned up our code just to make it better before moving on. We need to clean it up a bit more.

We will use the same process clean up our code: make a small change to the code, run the tests to be sure we haven't broken anything, and repeat.

Exercise: Preparing to Add the New Feature

Work in groups of 2-3 to do the following:

Choosing Our Design

What options do we have?

How do we choose among them? We have already seen two guidelines to help us:

... there are more. We will learn more throughout the course.

... they are not absolute rules. We might prefix them "Whenever possible, ..." or "Ideally, ...".

... they will often conflict with one another. Our job is to find a happy balance.

In this case, I choose to factor out a Frame class. It satisfies our second design guideline and is nearly as simpler (or even simpler!?) than the alternatives.

... this is design ...

... "But couldn't we just have planned ahead and used frames in the first place? Yes, but how far ahead? Can I plan *too* far ahead? What's the danger in that?"

... refactoring to clean up ... makes a *better program*, not a more complete one ... reading versus writing ...

The Language of Objects

A class is a set of objects, or the Java source code that describes such a set.

An instance is a member of a class, or the Java value created via a class's constructor.

An object-oriented program is a set of objects that collaborate to achieve a goal.

When we speak of "objects", we usually mean instances of some class, whether a specific Java instance or a general member of the class.

Similar objects, such as the frames in a bowling game, can probably be described with a single Java class.

One class in a Java program is not like the others, not a description of a set of objects. It contains the main() method that launches the program. The main() method creates one or more objects and sends one of them a message to begin execution. It is the "class we run". You can put a main() method in any Java class, but we will always make main() the only method in its class (plus any helper methods for processing the command-line arguments passed to main()).

If an object-oriented program is a set of objects that collaborate to achieve a goal, then to start a program we must somehow create at least one object and send it a message to request some service. We can think of an object-oriented program as a simulation of a part of the world, usually some subset of the real world augmented with objects that make the system work. This world is populated with objects that send each other messages. Again, though, we must somehow create the world and populate it with at least one object that can take things from there. In this metaphor, main is the Big Bang that creates the universe -- or the Hand of God.

How do objects collaborate? They send one another messages. In response to a message, an object executes the method associated with the message that it receives, both names and arguments.

A big part of designing an object-oriented system is deciding what messages each object should respond to. The set of messages to which an object responds is called its interface. As the semester progresses, you will take a larger role in designing the interfaces of objects, but early on you will implement classes for which much of the interface has already been designed.

Like a class, an interface also describes a set of objects -- the set of objects that respond to a particular set of messages -- and so is often used in Java programs as a way to describe what objects a program uses.

On Homework

Anyone who was not able to submit Homework 0 needs to e-mail me ASAP.

Any questions about Homework 1?

Wrap Up

Eugene Wallingford ..... ..... January 20, 2005