Quick Index
Video


Video accompanying this page...

Problem Statement


Problem Statement
For a turtle graphics system, design a simple (non animated) and animated turtle. Allow the turtle to have a circular, rectangular or elliptical shape.

The objects must be able to perform the behaviors shown.

Note that this is a slight variation of "Example #1", to demonstrate some different twists to three normalization steps.
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
drawOn(canvas)   drawAnimationOn(canvas)
moveBy(vector)   moveBy(vector)
scale(factor)    scale(factor)
setColor(color)  setColor(color)
setStyle(style)  setStyle(style)
turn(angle)      turn(angle)
forward(dist)    forward(dist)


Context (Environment) - The Given Goody Bag


We want to know the problem context (environment). This will tell us what other objects are available so that we an reuse and not re-invent.

Object Types in Goody Bag
Here are some available object types.

We have a general super-type "Shape" and specific sub-types "Circle", "Rectangle" and "Ellipse".
                Shape
                  |
  ----------------+----------------
  |               |               |
Circle        Rectangle        Ellipse
Behaviors in Goody Bag
The behaviors are declared on the general super-type "Shape", and inherited by the sub-types.
   Shape
------------------------
(behaviors/methods)
drawOn(canvas)
moveBy(vector)
scale(factor)
setColor(color)
setStyle(style)


Initial Design


We start our design by using the problem statement along with research to come up with an initial design.

Initial Design
In this case, we get lucky, and the problem statement gives us an initial design.
   Simple          Animated
    Turtle          Turtle
--------------------------------
(behaviors/methods)
drawOn(canvas)   drawAnimationOn(canvas)
moveBy(vector)   moveBy(vector)
scale(factor)    scale(factor)
setColor(color)  setColor(color)
setStyle(style)  setStyle(style)
turn(angle)      turn(angle)
forward(dist)    forward(dist)


Getting Organized


Overview


Before starting the object design normalization process, we'll get a bit organized.

Organizing Steps


Initial Design
Our starting point is the initial design.

Let's get organized.
Simple         Animated
Turtle          Turtle
--------------------------------
(behaviors/methods)
drawOn       drawAnimationOn
moveBy       moveBy
scale        scale
setColor     setColor
setStyle     setStyle
turn         turn
forward      forward
Identify Common Methods
We first identify common methods between the object types.

We have highlighted all the common methods. Only one method, for each object type, is not common.

We'll identify this common group as "COMMON-1" (there is no magic in the name -- any name that makes sense to you).

NOTE WELL -- The only reason we're using a group here is to abbreviate our documentation.
Simple         Animated
Turtle          Turtle
--------------------------------
(behaviors/methods)
drawOn       drawAnimationOn
moveBy       moveBy
scale        scale
setColor     setColor
setStyle     setStyle
turn         turn
forward      forward
Method Group "COMMON-1"
The method listing for group "COMMON-1".
COMMON-1 Methods:

Updated Initial Design
Now we update the design.

It's a bit more concise isn't it?
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMMON-1         COMMON-1
drawOn           drawAnimationOn

1NF - Use Components


Overview


First normal form (1NF) is when the design includes any sub-components (e.g., "ivars") that we can delegate work to (reuse logic).

We ask this question:

Could components (ivars) be added to provide required functionality?

Performing First Normal Form (1NF)


The following are the steps to attain 1NF.

Initial Design
Given an initial design.
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMMON-1         COMMON-1
drawOn           drawAnimationOn
Method Group "COMMON-1"
Given method group "COMMON-1" (within initial design).
COMMON-1 Methods:

Context
This is our problem context.

The problem context is like a goody bag of available reusable components.
                Shape
                  |
  ----------------+----------------
  |               |               |
Circle        Rectangle        Ellipse

   Shape
------------------------
(behaviors/methods)
drawOn
moveBy
scale
setColor
setStyle
Identify Redundant Methods
The highlighted methods show us methods are redundant (already coded in a potential component).

Let's move these redundant methods into a new method group "COMPONENT-1". The group name will help us remember these methods will be delegated to a component.
COMMON-1      Shape
Methods      Methods
---------   ----------
moveBy	    moveBy
scale	    scale
setColor    setColor
setStyle    setStyle
turn
forward
Method Group "COMPONENT-1"
Here is the new method group "COMPONENT-1" from the previous step.
COMPONENT-1 Methods:

Updated Method Group "COMMON-1"
Just a little housekeeping.

We remove the methods we identified as redundant (component) from the "COMMON-1" method group.
COMMON-1 Methods:

Updated Initial Design
The updated initial design.
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMPONENT-1      COMPONENT-1
COMMON-1         COMMON-1
drawOn           drawAnimationOn
Normalization Question
Now we ask the key question to allow us to achieve "first normal form":

  • Could components (ivars) be added to provide required functionality?


   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMPONENT-1      COMPONENT-1
COMMON-1         COMMON-1
drawOn           drawAnimationOn


In the previous step we determined that we have a large group of methods "COMPONENT-1" that can be delegated to components.

Therefore, the answer is yes. This is called code reuse.
Available Components
We know that all of these component types understand the methods we have grouped into "COMPONENT-1".
                Shape
                  |
  ----------------+----------------
  |               |               |
Circle        Rectangle        Ellipse
Components Design Try 1
Here is our first cut at adding components.

Each of our turtle object types now has a "shape" component.
SimpleTurtle    AnimatedTurtle
  |                 |
 shape            shape
  |                 |
  +---- aShape      +---- aShape
Components 'HAS-A' Check
We should cross-check as we go.

So we do a quick a 'HAS-A' check to help verify the components. Yes, the "has-a" statements sound reasonable. ✔
SimpleTurtle has-a Shape
AnimatedTurtle has-a Shape
First Normal Form (1NF) Achieved
We have achieved first normal form -- a.k.a. "composition (components)".

The important thing here is that all the methods in the "COMPONENT-1" group are delegated methods which are effectively "freebies" (no new logic needed).
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMPONENT-1      COMPONENT-1
COMMON-1         COMMON-1
drawOn           drawAnimationOn

2NF - Generalize Components


Overview


Second normal form (2NF) is when all components in the design are generalized where practical.

We ask this question:

Could any of the component types be more general?

Performing Second Normal Form (2NF)


Rule 2NF - Generalizing Components
We review the designed components (highlighted).

We then ask:
  • Could any of the component types be more general?
SimpleTurtle    AnimatedTurtle
  |                 |
 shape            shape
  |                 |
  +---- aShape      +---- aShape
Review Component Diagrams
We review the type diagrams (or class diagrams).

We now should be able to answer this question:
  • Could any of the component types be more general?



Our design is already using the most general type ("Shape"). Note that (per the diagram) shape is more general, and the three sub-types are more specific.

Therefore, the answer is no -- the design is already in second normal form.

Thus, no changes are needed to achieve 2NF.
                Shape
                  |
  ----------------+----------------
  |               |               |
Circle        Rectangle        Ellipse


3NF - Use Inheritance


Overview


Third normal form (3NF) is where common supertypes have been added (where practical) to eliminate redundancy

We ask this question:

Do two or more of the designed object types have redundant components or functionality?

Rule 3NF - Inheritance
First let's review the 2NF design.

And then ask: Do two or more of the designed object types have redundant components or functionality?

The answer is a resounding "YES". The components and all the methods are repeated (redundant) on the different turtles.
SimpleTurtle    AnimatedTurtle
  |                 |
 shape            shape
  |                 |
  +---- aShape      +---- aShape

   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
COMPONENT-1      COMPONENT-1
COMMON-1         COMMON-1
drawOn           drawAnimationOn
Component Type Check
We check to make sure the component types are equivalent.

The components all are of type "Shape", so the check passes. ✔.

If the compared components were of type "Apple" and "Orange" then these components would not be redundant.
SimpleTurtle    AnimatedTurtle
  |                 |
 shape            shape
  |                 |
  +---- aShape      +---- aShape
Trying a Supertype
Take a shot at designing a supertype.


         Turtle
           |
  ---------+---------
  |                 |
Simple           Animated
Turtle            Turtle


We try a supertype "Turtle" (we simply choose a name that sounds reasonable).
Sub-Type 'IS-A' Check
We do a 'IS-A' check to make sure the inheritance is reasonable.

Yes, the "is-a" statements sound reasonable. The check passes. ✔.

SimpleTurtle is-a Turtle
AnimatedTurtle is-a Turtle
Turtle Sub-Components (Ivars)
Our designed turtle has one sub-component
Turtle
  |
shape
  |
  +---- aShape
Turtle Behaviors (Methods)
Our designed turtle has behaviors (methods)
COMPONENT-1 (group)
COMMON-1  (group)
SimpleTurtle and AnimatedTurtle
Our two sub-types are lightweight -- they only need to support one method each (highlighted).
         Turtle
           |
  ---------+---------
  |                 |
Simple           Animated
Turtle            Turtle

   Simple          Animated
   Turtle           Turtle
--------------------------------
drawOn           drawAnimationOn
Third Normal Form (3NF) Achieved
We have achieved third normal form (3NF) -- a.k.a. "inheritance".

Remember that all of the methods are trivial delegated methods except the two highlighted.

Thus, we only have new logic in three methods! (and a good portion of that logic may also be delegated)

Note that, for the final design, we have expanded out the method groups so we list the actual method names.
         Turtle
           |
  ---------+---------
  |                 |
Simple           Animated
Turtle            Turtle

    Turtle
------------------------
(components/ivars)
shape
(behaviors/methods)
moveBy*
scale*
setColor*
setStyle*
turn
forward

    SimpleTurtle
------------------------
drawOn*

    AnimatedTurtle
------------------------
drawAnimationOn

*delegated method
Component "shape" is object type "Shape"

Example #2 Conclusion


Overview


This example showed different process of the object design normalization process.

In some cases we'll make design changes for a normalization step and in some cases not.

In this example, we did not need to make a design change to achieve second normal form.

Compare Final to Initial Design


Recall Our Initial Design
In our initial design we needed to complete about fifteen methods.
   Simple          Animated
   Turtle           Turtle
--------------------------------
(behaviors/methods)
drawOn(canvas)   drawAnimationOn(canvas)
moveBy(vector)   moveBy(vector)
scale(factor)    scale(factor)
setColor(color)  setColor(color)
setStyle(style)  setStyle(style)
turn(angle)      turn(angle)
forward(dist)    forward(dist)
Final Design (3NF)
Our design includes three object types and three methods.

The delegated methods are basically "freebies" (we use the component's logic).

Fifteen methods simplified down to four methods. As they say "less is more".
         Turtle
           |
  ---------+---------
  |                 |
Simple           Animated
Turtle            Turtle

    Turtle
------------------------
(components/ivars)
shape
(behaviors/methods)
moveBy(vector)*
scale(factor)*
setColor(color)*
setStyle(style)*
turn(angle)
forward(dist)

    SimpleTurtle
------------------------
drawOn(canvas)*

    AnimatedTurtle
------------------------
drawAnimationOn(canvas)

*delegated method
Component "shape" is object type "Shape"