PHP

Moving Beyond Libraries

Imagine I were to begin writing a web application for an online boating parts merchant. This business will offer products from its warehouses and also interface directly with a partner company that will sell navigation equipment (radios, GPS devices, weather-radar, and so on) through the boating company's web site. Customers will be able to browse through the products, learn more about them, and purchase them online.

To support this functionality, I could imagine writing a little code library for use in the product pages of Beth's Boating Supplies online store. I would first identify the data required to fully describe a product:

  • A product identification number (PID)

  • The name of the product

  • A complete description of the product

  • The cost of the product

  • The location of the product, whether in my warehouses or being referenced via my navigation partner

I could choose to represent this in an array, with the data names being the keys of the array and write ourselves a function to create a product representation, as follows:

<?php
  define('LOCAL_PRODUCT', 1);
  define('NAVIGATION_PARTNER_PRODUCT', 2);
  function prod_create_product_wrapper
  (
    $in_pid,
    $in_name,
    $in_desc,
    $in_price,
    $in_location
  )
  {
    return array("ProductID" => $in_pid,
                 "Name" => $in_name,
                 "Description" => $in_desc,
                 "Price" => $in_price,
                 "Location" => $in_location);
  }
?>

I then might start writing other routines that would operate on this new product representation, such as a routine to find out if the product is in stock and another routine to mark a certain number of the product as purchased and as part of an order that the user has placed.

<?php
   function prod_get_stock_number($in_product)
   {
     // return an error on invalid product.
  if ($in_product == NULL) return -1;
  if ($in_product["Location"] == LOCAL_PRODUCT)
  {
    // go to local database and find out how many I
    // have, returning this number, 0 if none.
  }
  else if ($in_product["Location"] == NAV_PARTNER)
  {
    // communicate with my navigation partner's systems
    // and ask them how many are left.
  }
  else
  {
    // this is an error -- I'll talk about how to deal with
    // this more elegantly later.
    return -1;
  }
}
function prod_add_to_order
(
  $in_product,
  $in_number,
  $in_shipinfo
)
{
  // return an error if the product is invalid.
  if ($in_product == NULL) return -1;
    if ($in_product["Location"] == LOCAL_PRODUCT)
    {
      // do the work in my databases and other facilities
      // to mark $in_number of this product as sold and
    }
    else if ($in_product["Location"] == NAV_PARTNER)
    {
      // go to my partner and tell him $in_number of this
      // product are sold and will need to be shipped.
    }
    else
    {
      // I'll talk about more robust errors later.
      return -1;
    }
  }
?>

This solution has the advantage of being reasonably easy to code up; a possible conception of this is shown in Figure. However, it has a number of important drawbacks, which I would like to address:

  • I have to create and pass around the array used to hold all the data for a product. I also have to create code at the beginning of each function to which this array is passed to make sure it's not NULL and perform any other data validation.

  • Every time I want to add support for a new product location (for example, to add a new partner whose products will be sold directly from their warehouses), I have to add more constants, more cases to the various functions to handle the new types, and new fields to the product array.

  • I have no close coupling between the product representation's data and the functions that operate on them, nor is there any real protection of the data anybody can look at and modify them. I simply have random bags of properties and functions.

Figure 1. Programs manipulating and passing around data between functions.


You can imagine entire categories of data and operations on them I would like to couple more tightlyusers, accounts, shipping orders, customer service requests, or even simple files on the local file system.

Fortunately, there is a reasonably elegant solution to this problem.


by BrainBellupdated
Advertisement: