Comp201: Principles of Object-Oriented Programming I
Spring 2008 -- Shape Calculator, part 2   


Instantiating a Fixed Shape and Displaying Its Area on a Label

Before starting this section, copy all the code from part 1 into your part2 subdirectory and make any modifcations to the code in part2. Do NOT modify your part1 code!

In this section we will start the process of creating a factory that creates shapes. In the spirit of eXtreme Programming ("XP"), we will continue to build our system slowly, adding in functionality bit by bit.

But before we start making code to process shapes, we must first define what it means to have a shape and to have a factory that produces them:

Interfaces for Shapes and Factories for Shapes

The interfaces to the key abstract elements of our system define the semantics, the meaning, of those objects in our system. In geek-speak, we are effectively creating the "Application Programming Interface" or "API" to our system. In a nutshell, we are defining the manner in which the invariant parts of the code communicate with the variant parts of the code. In this case, the invariant part will be the GUI portion (technically, including the abstract interfaces), and the variant part will be the concrete shapes and the concrete factories that create them.

So, what is a shape?

A shape could be many, many things with many different types of behaviors. So in the spirit of KISS (for this class: "Keep It Simple Smartypants!"), we will simple say that a shape is intelligent and can calculate its area and paint itself onto a graphics object at a given (x,y) coordinate.

package shapecalc;



import java.awt.*;   // needed for Graphics class



public interface IShape {

    public abstract double getArea();

    public abstract void paint(Graphics g, int x, int y);

}

If we need additional functionality later, we will add it then.

So a shape factory is thus something that makes IShapes:

package shapecalc;



public interface IShapeFactory {

    public abstract IShape makeShape();

}

Once again, we will add additional functionality later as needed.

Let's turn the argument around for a minute. If an IShapeFactory makes an IShape, then what is an IShape?

Consider this object:

new IShape() {

	private double b1 = 3.14;

	private double b2 = 2.72;

	private double h = 6.022;

	

	public double getArea() {

		return (b1+b2)*h/2.0;

	}

	

	public void paint(Graphics g, int x, int y) {

		// some pretty image

	}

}

Is this an IShape? Does it act as an IShape should? If something walks like a duck, quack like a duck and swims like a duck, is it a duck?

(FYI, the above shape acts like a trapezoid.)

An IShape is an object that can calculate its area and paint itself onto a graphics object in a manner as defined by the factory that made it. A square does "square" things because it was made by a square factory. Bottom line here: it doesn't matter what we call any given shape, just that it has the abstract behaviors of a shape. A shape factory is an object that guarantees that any shape it creates will be properly behaving shape.

Making a Shape

Let's slowly integrate IShape and IShapeFactory into our GUI framework:

  1. In a new shapecalc.shapes package, create a concrete implementation of an IShapeFactory called SquareFactory.
  2. Implement SquareFactory's makeShape() method using an anonymous inner class to create the new instance of IShape.
  3. In ShapeCalc, remove the stub code from the button listener and replace it new stub code:
    1. Call to SquareFactory's singleton to make a shape.
    2. Take that shape and set the areaLbl's text to "Area: "+ the shape's area.
  4. Run and test your program to see if your button can now make a viable shape object.

So far so good!

On to part 3!

 


Last Revised Thursday, 03-Jun-2010 09:50:28 CDT

©2008 Stephen Wong and Dung Nguyen