Hack73.Write Portable Code with Bridges


Hack 73. Write Portable Code with Bridges

Use a Bridge pattern to hide the implementation on an object, or to change the implementation based on the environment.

In one of my jobs, working for a company that shipped a very large cross-platform C++ application, we used the heck out of the Bridge pattern. The Bridge pattern allows you to hide a portion of the implementation of a class in another class, either because you want to hide the code from other implementers or because the implementation of a portion of the code is platform specific.

I've taken the platform-specific approach in this hack to show the benefits of a bridge. Figure 7-7 shows the relationship between two classes, TableCreator and TableCreatorImp. The role of the table creator is to create tables in the target database. The implementation class, TableCreatorImp, is defined in another file, which is included from a database-specific directory.

This flexibility allows for one version of the code specific to Oracle and another for MySQL (or any other database). This is handy, as each database has a different syntax for creating tables.

Figure 7-7. The TableCreator class and its implementation class


7.8.1. The Code

Save the code in Example 7-7 as bridge.php.

Example 7-7. The base Bridge pattern class
 <?php require( "sql.php" ); class TableCreator {   static function createTable( $name )   {     TableCreatorImp::createTable( $name );   } } TableCreator::createTable( "customer" ); ?> 

Save the code in Example 7-8 as mysql/sql.php.

Example 7-8. An example implementation class for MySQL
 <?php class TableCreatorImp {   static public function createTable( $name )   {     echo( "MySQL version of createTable for $name\n" );   } } ?> 

Save the code in Example 7-9 as oracle/sql.php.

Example 7-9. An example implementation for Oracle
 <?php class TableCreatorImp {   static public function createTable( $name )   { echo( "Oracle version of createTable for $name\n" );   } } ?> 

7.8.2. Running the Hack

Running this code requires some extra command-line parameters, instructing the PHP interpreter to include either the mysql or oracle directory in the include path (and therefore using that database-specific bridge). Here is the version using the MySQL code:

 % php -d include_path='.:/usr/local/php5/lib/php:mysql' bridge.php MySQL version of createTable for customer 

Here is the version using the Oracle code:

 % php -d include_path='.:/usr/local/php5/lib/php:oracle' bridge.php Oracle version of createTable for customer 

It's not rocket science, so you should get the idea pretty quickly. TableCreator actually is implemented by one of several versions of TableCreatorImp, located in platform-specific directories.

Obviously the code here does not create tables; this is merely a framework that would need some additional code to actually work. But the specifics of building tables in different databases aren't germane to teaching the Bridge pattern (that's fancy talk for "You can figure that out on your own").

One big drawback of bridges is that you can't extend your implementation-specific classes. In this case, this isn't an issue, as all the methods in the implementation classes are static. But for regular objects with nonstatic methods, the implementation class derives from the base nonimplementation class. For example, CButtonImp derives from CButton. To extend the behavior, the code would need to derive from CButtonImp, which is hidden. Arguably, however, this is more of a problem in compiled languages like C++.



PHP Hacks
PHP Hacks: Tips & Tools For Creating Dynamic Websites
ISBN: 0596101392
EAN: 2147483647
Year: 2006
Pages: 163

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net