Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

examp4.cpp

This example is to show use of the Bridge and Prototype patterns.

In our scenario we want to enable the choice of car engines between six (6) and eight (8) cylinders. The advantage that the Bridge pattern brings to the problem domain is that it can be dynamically configured to work with either concrete engine type. We have concrete engines as types instead of a factored engine with a cylinder attribute for example purposes.

Because the base Bridge calls cloneImplementation in EngineBridge the Prototype pattern is suited for Engine becuase we want to create a Engine based on the prototype that the Bridge is responsible for.

See also:
Engine.hpp EngineBridge.hpp

/*
  CoreLinux++ 
  Copyright (C) 2000 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/   

#include <Common.hpp>

using namespace corelinux;

#include <EngineBridge.hpp>         // The Bridge
#include <SixCylinderEngine.hpp>    // Concrete Engine class
#include <EightCylinderEngine.hpp>  // Concrete Engine class

#include <iostream>
#include <exception>

//
// In module function prototypes
//

int   main( void );                       

//
// Functions that work with Engine types
//

EngineBridgePtr   selectEngine( void );
void              displayEngineStats( EngineBridgePtr );
void              upgradeEngine( EngineBridgePtr );

void  handleAssertion( AssertionCref );
void  handleException( ExceptionCref );   

int main( void )
{

   //
   // Practice gracefull exception management
   //

   cout << endl;

   try
   {
      //
      // First get any engine
      //

      EngineBridgePtr   anEngine( selectEngine() );

      if( anEngine != NULLPTR )
      {
         //
         // Now excercise the Bridge
         //

         displayEngineStats( anEngine );

         upgradeEngine( anEngine );

         displayEngineStats( anEngine );

         delete anEngine;

      }
      else
      {
         cout  << "We have bicycles too!" << endl;
      }

   }
   catch( AssertionRef aAssert )
   {
      handleAssertion(aAssert);
   }
   catch( ExceptionRef aException )
   {
      handleException(aException);
   }
   catch( std::exception & e )
   {
      cerr  << e.what() << endl;
   }
   catch( ... )
   {
      cerr  << "Unknown exception." << endl;
   }

   return 0;               
}


//
// Select the engine of choice
//

EngineBridgePtr   selectEngine( void )
{
   EngineBridgePtr   aPtr(NULLPTR);
   Cylinders         numberRequested(0);

   cout  << endl;
   cout  << "Request the number of cylinders for your engine : ";
   cin   >> numberRequested;
   cout  << endl;

   if( numberRequested == 6 )
   {
      aPtr = new EngineBridge( new SixCylinderEngine );
   }
   else if( numberRequested == 8 )
   {
      aPtr = new EngineBridge( new EightCylinderEngine );
   }
   else
   {
      cout << "Sorry, we don't stock those." << endl;
   }
   return aPtr;
}

//
// Show it
//

void  displayEngineStats( EngineBridgePtr aPtr )
{
   cout  << endl;
   cout  << "The number of cylinders in your engine = " << 
      aPtr->getCylinders() << endl;
}

//
// Here we upgrade. Because the Bridge requires that
// a implementation substitution is cloned, we 
// use a automatic instance as a prototype.
//

void  upgradeEngine( EngineBridgePtr aPtr )
{
   Cylinders         numberRequested(0);

   cout  << endl;
   cout  << "Request the NEW number of cylinders for your engine : ";
   cin   >> numberRequested;
   cout  << endl;

   SixCylinderEngine    aSix;
   EightCylinderEngine  aEight;

   if( numberRequested == 6 )
   {
      aPtr->upgradeEngine(&aSix);
   }
   else if( numberRequested == 8 )
   {
      aPtr->upgradeEngine(&aEight);
   }
   else
   {
      cout << "Sorry, we don't stock those." << endl;
   }

}

//
// Peform default (just show it)
//

void  handleAssertion( AssertionCref aAssert )
{
   cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << 
      "Assertion: ";

   if( aAssert.getType() == Assertion::NEVERGETHERE )
   {
      cerr << "NEVER_GET_HERE";
   }
   else
   {
      if( aAssert.getType() == Assertion::REQUIRE )
      {
         cerr  << "REQUIRE";
      }
      else if( aAssert.getType() == Assertion::ENSURE )
      {
         cerr  << "ENSURE";
      }
      else if( aAssert.getType() == Assertion::CHECK )
      {
         cerr  << "CHECK";
      }
      else 
      {
         cerr  << "ASSERT";
      }
      cerr << "( " << aAssert.getWhy() << " )";
   }

   cerr << endl;
}

void  handleException( ExceptionCref aExcp )
{
   cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" <<
      "Exception: " << aExcp.getWhy() << endl;
}

/*
   Common rcs information do not modify
   $Author: prudhomm $
   $Revision: 1.3 $
   $Date: 2000/08/31 22:49:01 $
   $Locker:  $
*/



This is the CoreLinux++ reference manual
Provided by The CoreLinux Consortium