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. The following table shows how this model of pizza is represented in Java and compares it with an equivalent Scheme representation.
OO Design in Java | Data-directed Design in Scheme (Beginner's Level) |
/** * 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. |
/** * 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; public Rectangle(double w, double h) { _width = w; _height = h; } public double getArea() { ... _width ... ... _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; } } |
UML is a de-facto standard for diagramming OO designs. It is language neutral.
The above Pizza design is represented in UML as follows.