Metaprogramming


Introduction | Concepts of Metaprogramming

Metadata Example | Class Exercise | Homework Problem

Return To Home Page


Introduction

Do Not Write Dodo Code

This is a picture of the dodo bird.   It lived happily on the island of Mauritius until humans came and took over their island.   They couldn't fly and were gentle creatures, so they fell easy prey to man and the other animals (dogs, pigs, rats) they introduced to the island.   The dodo's habitat was also destroyed by humans.   They could not adapt to the harsh environment that humans introduced to them, so their numbers dwindled and they became extinct.

You should learn from the dodo.   Your code should be flexible and adaptable to change.   A new demand could be imposed on you because of a change in business rules, a change in the law, or a change in your boss' preferences.   If your code cannot adapt to these changes, it will quickly become extinct just like the dodo.
Back to Top of Page

Concepts of Metaprogramming

What is metadata?
Why is metadata used? General rule: Program for the GENERAL case, put specifics outside the compiled code base.
Back to Top of Page

Metadata Example

Calculate The Price of Pizza

This example illustrates the advantage of metadata over hardcoding when calculating the price of pizza.   The example was kept simple in order to illustrate the concept clearly.   Size and toppings were the only attributes dealt with, but crust and specialty pizzas could also be added to the equation.

Hardcoded Version

If you hardcode the pizza calculation, you will have to change the attributes and their prices for each pizza chain.   For example, if one chain offers personal and another does not, you must account for that in your code and equations.   Likewise, if a small is $8.00 at one place and $10.00 at another, you must make this change to your equations.

After making all these changes, you then have to recompile your code.   This process can be tedious and time consuming, especially when other attributes are added such as crust type and specialty pizzas.

import java.math.BigDecimal;

public class Pizza extends Object {

      // arguments for Pizza are:
      // size (personal, small, medium, large, xlarge)
      // number of toppings
      public static void main(String [] args) {
            String size, toppings;
            BigDecimal price = new BigDecimal(0);
            int numToppings;

            try {
                  size = new String(args[0].trim( ).toLowerCase( ));
                  toppings = new String(args[1].trim( ));
                  numToppings = Integer.parseInt(toppings);

                  if (size.equals("personal")) {
                        price = (new BigDecimal(5)).add(
                                     (new BigDecimal(numToppings)).multiply(new BigDecimal(0.25)));
                  }
                  else if (size.equals("small")) {
                        price = (new BigDecimal(8)).add(
                                     (new BigDecimal(numToppings)).multiply(new BigDecimal(0.75)));
                  }
                  else if (size.equals("medium")) {
                        price = (new BigDecimal(10)).add(
                                     (new BigDecimal(numToppings)).multiply(new BigDecimal(1.00)));
                  }
                  else if (size.equals("large")) {
                        price = (new BigDecimal(12)).add(
                                     (new BigDecimal(numToppings)).multiply(new BigDecimal(1.25)));
                  }
                  else if (size.equals("xlarge")) {
                        price = (new BigDecimal(14)).add(
                                     (new BigDecimal(numToppings)).multiply(new BigDecimal(1.50)));
                  }
                  else {
                        System.out.println("We don't have that size pizza");
                  }
            } catch (Exception e) {
                  System.out.println("You screwed up:" + e);
            }
            System.out.println("Your pizza costs: $" + price);
      }
}

For a copy of Pizza Hardcoded, click
here .
Version Using Metadata

When metadata is used to create the pizza price calculation, you need only make changes in your metadata file.   For example, if the pizza chain does not offer a personal pizza, then you can just remove this from your metadata file.   Also, if a small pizza is $10.00 rather than $8.00, then you need only change the 8 to a 10 in your metadata file.

Since your main file only contains your equations, you do not need to compile again.   Any changes you make in your metadata file will immediately take effect in your equations without any wasted time fiddling with equations and recompiling.

*Metadata File Called pizzaData*

#pizzaData
#Wed Dec 04 11:25:12 PST 2002
size_personal=5
size_small=8
size_medium=10
size_large=12
size_xlarge=14
topping_personal=0.25
topping_small=0.75
topping_medium=1
topping_large=1.25
topping_xlarge=1.5

*Main File For Metadata Version*

import java.io.*;
import java.util.Properties;
import java.math.BigDecimal;

public class PizzaMeta extends Object {
      // arguments for Pizza are:
      // size (personal, small, medium, large, xlarge)
      // number of toppings

      public static void main (String [] args) {
            Properties pProp = new Properties( );
            String size, toppings;
            String sizeValue, toppingValue;
            BigDecimal price = new BigDecimal(0.00);
            int numToppings;

            try {
                  FileInputStream file = new FileInputStream("PizzaData");

                  pProp.load(file);
                  size = new String(args[0].trim( ).toLowerCase( ));
                  toppings = new String(args[1].trim( ));

                  numToppings = Integer.parseInt(toppings);

                  sizeValue = pProp.getProperty("size_" + size);
                  toppingValue = pProp.getProperty("topping_" + size);

                  price = price.add(new BigDecimal(sizeValue));
                  price = price.add((new BigDecimal(numToppings)).multiply
                              (new BigDecimal(toppingValue)));

            } catch (Exception e) {
                  System.out.println("You screwed up:" + e);
            }
            System.out.println("Your pizza costs: $" + price.toString( ));
      }
}

For a copy of PizzaMeta, click here .
Back to Top of Page

Class Exercise

Which of the following would be better represented as code within a program and which externally as metadata?

  1. Remembering ID and password on a browser.
    i.e. An email account like AOL or Hotmail.

  2. An editor's support for highlighting the syntax of various languages.
    i.e. Visual C++ or textpad highlights keywords such as private and public.

  3. Sample values and results for use in unit testing.

  4. Selection of database.
    i.e. mySQL or Oracle, etc.

Answers

  1. Metadata.
    There is an undefined number of IDs and passwords that are saved and are constantly changing.   Someone else can log in or you could change your password.

  2. Metadata.
    If Java introduces a new key word you only want to deal with metadata.   This eliminates the need to hack into code.

  3. Depends - we prefer hard-coded.
    You need this code for repetitious testing rather than flexibility.   When it is in code, then it will run faster.

  4. Metadata.
    If you want to accomodate people who use different databases, use metadata.
Back to Top of Page

Homework Problem

This homework example should get you used to utilizing metadata.   If you need some help, use the metadata example illustrated earlier to calculate the price of pizza.
Calculate GPA

Now you must show how to calculate GPA using metadata.   Think about grades and quality points used. Thus, equations for calculating GPAs for different schools WILL be different and should be dealt with using metadata.
Back to Top of Page