Today's menu:
A pizza has a price and a shape. We want to compute the price/area ratio. It is the shape that intrinsically "knows" how to compute its area. A shape is an abstract concept. The area of a shape is an abstract concept. A rectangle is a concrete and specific shape. A rectangle knows its own width and height and therefore can compute its area. A circle is a concrete and specific shape. A circle knows its own diameter and therefore can compute its area. In the table shown below, we describe how this conceptual view of a pizza is expressed in Java as an object-oriented (OO) model and compare it with an equivalent functional representation in Scheme. This OO pizza model involves the following fundamental concepts in OOP.
OO Design in Java | Data-directed Design in Scheme |
/** * A shape is an abstract entity that intrinsically knows how to compute its area. */ public interface IShape { public double getArea(); } |
;; A Shape is either ;; (make-Rectangle w h) where ;; w and h are numbers representing ;; the width and the height ;; or ;; (make-Circle r) where ;; r is a number representing the radius ;; contract: getArea: Shape -> number ;; purpose: ;; (getArea s) returns the area of s. |
/** * A rectangle is a shape. * It has a width and a height and * a way of computing its area using its width and height. */ public class Rectangle implements IShape { private double _width; private double _height; // Below is a very special construct in Java // called the constructor. It is used to // initialize an instance of a Rectangle to // a given width and height. public Rectangle(double w, double h) { _width = w; _height = h; } public double getArea() { // code may involve _width and _height } } |
(define-struct Rectangle(width
height)) ;; make-Rectangle, Rectangle-width, ;; Rectangle-height ;; are automatically generated |
/** * A circle is a shape. * It has a radius and a way of computing its area using its radius. */ public class Circle implements IShape { private double _radius; public Circle(double r) { _radius = r; } public double getArea() { ... _radius ... } } |
(define-struct Circle(
radius)) ;; make-Circle, Circle-radius ;; are automatically generated |
;; template ;; (define getArea (s) ;; (cond [(Rectangle? s) ;; ... (Rectangle-width s) ... ;; ... (Rectangle-height s) ...] ;; [(Circle? s) ;; ... (Circle-radius s) ...])) |
|
public class Rectangle implements
IShape { // ... public double getArea() { return _width * _height; } } |
;; actual code (define getArea (s) (cond [(Rectangle? s) (* (Rectangle-width s) (Rectangle-height s))] [(Circle? s) (* PI (Circle-radius s) (Circle-radius s))])) |
public class Circle implements
IShape { // ... public double getArea() { return Math.PI * _radius * _radius; } } |
|
/** * A pizza has a price and a shape. */ public class Pizza { private double _price; private IShape _shape; public Pizza(double p, IShape s) { _price = p; _shape = s; } public double getPrice() { return _price; } public IShape getShape() { return _shape; } } |
;; A Pizza is ;; (make-Pizza p s) where ;; p is a number representing the price, ;; and s is a Shape (define-struct Pizza(price shape)) ;; make-Pizza, Pizza-price, Pizza-shape ;; are automatically generated. |
UML is a de-facto standard for diagramming OO designs. It is language neutral.
The above Pizza design is represented in UML as follows.
Last revised 01/11/2005 by Dũng X. Nguyễn