Factory Method with Return Typing

factorymethodIf you do a Google search for “Factory Design Pattern,” thankfully, the first hits are “Factory Method….,” the correct name of the pattern that Gamma and his associates developed as a fundamental design pattern. I am not at all impressed by nit-pickers, and lest you think me petty by touching upon the notion of “Factory” vs. “Factory Method,” I hope this post will show you why including a factory method in a Factory Method design pattern is both important and necessary.

The Factory Method: Abstract with Concrete Operations

Some of the posts about the Factory Method are more about the idea of a factory than a method within the Creator (Factory) interface. What the key is, though, is to design an interface in the Factory with both abstract and concrete elements which return a concrete Product. The details of the factoryMethod() are left up to the concrete implementations to decide which one to implement. The factoryMethod() is abstract, but with PHP7, we can establish a return type. What is a return type? When stated, it is the type of data that a method must return. In earlier versions of PHP, using type hinting, only certain types of objects could be included in a method’s arguments. Now, though, you can add a return type to a method. For example, the factoryMethod() in this example includes an IProduct return type after the closing parenthesis in the function declaration:

   abstract protected function factoryMethod():IProduct;

Like the scalar variables discussed in a pervious post that could be typed as code hints in parameters, a return value of a scalar variable such as a string means the that the method must return a string, as you can see in the IProduct implementations. However, the factoryMethod is designed to return an instance of an IProduct (the object) implementation. While common in other languages, return types are newly added feature in PHP7.

The Elegance of the Factory Method

Every time I go over the original Design Patterns in the GoF book, I find something new. One of my favorite patterns is the Template Method. The method itself is concrete but the operations within the method are abstract. The Factory Method is the opposite. The factory method is abstract, but it is called by a concrete operation defined in the interface. (I use the term interface to reference both PHP interface type classes as well as abstract class types.) To be sure, The Gang of Four, have more than a single implementation suggested for the Factory Method pattern, but in the class diagram, the method is set up in the interface (Creator) as an abstract method along with a concrete method as shown in Figure 1:

Figure 1: Factory Method class diagram

Figure 1: Factory Method class diagram

Before continuing, run the program (Play) and download the source code (Download.) The program is one I’m using to build a path from Lambda Calculus to PHP. (To run the downloaded source files, you’ll need PHP 7.)

PlayDownload

Once you have the source code downloaded and a sense of what the program produces, you’ll better understand how the Factory Method pattern makes it easy to update the “products” showing the lambda calculus and the PHP program using functional methods. The Creator participant in this pattern (IFactory) includes two methods; one abstract and one concrete as shown in the following listing:

< ?php
abstract class IFactory
{
    //This class is the 'Creator' interface in the class diagram.
 
    protected $productNow;
 
    /*
     * Factory Method--returns concrete Product--reutrns any
     * implementation of IProduct--it programs to the Interface
    */
 
    abstract protected function factoryMethod():IProduct;
 
    /*
     * The createProduct() is identified as 'anOperation()' in the class digram
     * While it is a concrete method, it returns the factoryMethod()
     * an abstract method.
    */
 
    public function createProduct():IProduct
    { 
        return $this->factoryMethod();
    }
}
?>

The IFactory abstract class may appear to be both strange and broken. How can a concrete method (createProduct) return an abstract method (factoryMethod)? Far from being broken, it’s brilliant. It means that while the createProduct() must return a factoryMethod(), the factoryMethod() can be implemented any way the developer needs following the structure of the interface.

Thoughtful Structure and Easy Update

As a Creational type of design pattern, the Factory Method may have what some consider an unnecessarily fussy (and complex) structure to get a simple product. In this example, the product returns nothing but strings with some HTML embedded to display text messages. Wouldn’t it be just as effective and a lot easier to have a single object for each product using a single interface? Or even simpler, have a single class and just add a set of properties for each string? The answer to all of those questions is, Yes, of course. However, there’s a caveat: if your product is simple; so is the solution. In the examples on this blog, I’ve tried to clarify how to build different design patterns correctly and clearly. We were stuck with the following paradox:

The clearer a design pattern example, the less useful it appears to be.

So, while generating output from strings is no great shakes, the important point is to see how simple it is to make changes using the Factory Method pattern. For example, instead of generating strings, suppose each product requires calls to a MySql database, a jQuery-based mobile UI, and a JavaScript graphic handler (not jQuery). If you look at Figure 2, you can see how this implementation follows the class diagram in Figure 1. The HTML UI and CSS file call the Client:

Figure 1: Implementation of the Factory Method pattern

Figure 1: Implementation of the Factory Method pattern

Okay, that’s a bit more complex, but the real issue is how to have several such products generated by the same program, each needing regular (e.g., daily) update and changes for several such products. By having a Factory Method take care of all of the new creations (additions and changes), you can rest assured that as the program gets bigger,as long as you follow the rules in the design pattern (attend to the rules laid down in the interfaces), not only will it be easier to maintain, but it will be less prone to bugs.

The Factory: The Method Returns Help the Developer

In creating the examples using PHP7 and the new function return types, I kept running into errors as I attempted to return product instances. The errors indicated that I was returning strings instead of objects (product instances). Because of the return typing, I was able to find the errors and return the objects, which in turn returned the strings from the products. First, look at the IFactory implementations:

< ?php
class FactoryID extends IFactory
{
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaID();
        return $this->productNow;
    }
}
?>
 
< ?php
class FactoryApp extends IFactory
{  
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaApp();
        return $this->productNow;
    }  
}
?>
 
< ?php
class FactoryPythag extends IFactory
{  
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaPythag();
        return $this->productNow;
    }  
}
?>

As you can see each implementation of the factory interface differs only slightly. Each calls a different product implementation. Because the createProduct() method is concrete, it does not need further implementation—even though the method calls an abstract method. (Note: Please remember that each class is saved as the class name with the “.php” extension.)
Continue reading ‘Factory Method with Return Typing’

Share

PHP 7 Scalar Variable Type Hinting

php7WARNING: The following program only works with PHP 7 installed. After getting my first PHP 7 development platform up and running on one of my Macs, I thought it’d be a good idea to do a Q & D post on working with typed (or code hinted) scalar variables. It turns out that the type hinting with scalar variables has some interesting consequences.

Not to oversell the idea of type hinting in scalar variables, but they are important for maintaining a well-functioning program; especially one using OOP and design patterns. In this simple example, I created a class with four methods. Each of the four methods illustrate a different type of scalar type hinting; float, int, string and bool. As the most common types of variable, you can add them to the existing categories of hinted type: array, and named class/interface.

A Class to Show Off Typed Scalar

The following class uses static typing and a lambda function to illustrate that scalar variable type hinting can be used in any OOP context. Each of the first three methods, calls the next method so that you can see how all four of the scalar types work:

<?php
class Scalar
{
    private static $scalar1,$scalar2,$scalar3,$scalar4;
    //client request
    public static function request(float $num)
    {
        //float
	self::$scalar1 = $num;
        echo self::$scalar1 * 5 . '<br />';
        self::noFloat(4.1);
    }
 
    private static function noFloat(int $singular)
    {
        //int
	self::$scalar2 = $singular;
        echo self::$scalar2 * 5 . '<br />';
        self::talker("Hello ");
    }
 
    private static function talker(string $word)
    {
        //string
	self::$scalar3 = $word;
        echo self::$scalar3 . " world!". '<br />';
        self::truth((6 > 7));
    }
 
    private static function truth(bool $fact)
    {
        //bool
	self::$scalar4 = $fact;
        $result=function(bool $x) { return $x ? "It is true" : "Not true!";};
        echo $result(self::$scalar4);
    }   
}
Scalar::request(4.1);
?>

The initial request calls for a floating point value (float) and uses 4.1 as an argument value. The result shows 20.5. However, in the noFloat() method, an int type is used and the returned value is 20 since the argument (4.1) is automatically changed to an integer (4)–with values always rounded down. The string is a simple string (“Hello “) and the Boolean method’s, truth(), argument is the expression (6 > 7), which is false. Note also, that in the lambda function (anonymous function) assigned to the local variable $result, also has a bool data type hint. So, the type hint bool is used twice in the truth() method. By using a simple lambda function, you can better see the truth value of the Boolean.

This short post is simply to illustrate how the new scalar type hints can be used in an OOP class that includes both static and local variables as well as a lambda function. There’s more to the new PHP 7 typing that will be touched on in the near future.

Share

PHP 7 / PHPNG: Speed and Better Data Typing

PHP7Hello PHP7

Last Wednesday (11/11/15), we drove up from Connecticut to the Boston PHP meeting where Zend’s Cal Evans gave a very informative talk on PHP 7 at the Microsoft New England Research and Development (N.E.R.D.) center next to the MIT campus. (PHP 7 is also known as PHPNG with NG = “Next Generation”.) It was well-worth the 200 mile (332K) round trip as my compadre (a Drupal guy) and I were examining every nuance of PHP 7 and what it meant for design patterns, functional programming and other PHP-based apps like Drupal and Word Press. The short version is that it means better speed. Fortunately, most of the other new features extend what we’ve been doing on this blog since its inception; namely, using mysqli instead of mysql; creating constructor functions using __construct instead of the class name; and using type hinting where possible.

Speed

I have not worried about speed for years. The bandwidth and processor speeds have regularly increased to the point where structure was more important than speed to me. Besides, there wasn’t much I could do about multi-core programming since PHP does not support concurrent development. (Maybe in version 8). I’ve already had a rant about my hosting service on my other blog; so I’ll not repeat it here; but get a hosting service that supports PHP 7.

So what about speed? It’s roughly twice what it used to be. Figure 1 shows some early timing data (which varies all over the place depending on the app you’re using). However, it does show how the speed since PHP 5.0 increased significantly. For the sake of argument, let’s say it’s about twice as fast as PHP 5.6.

Figure 1: Speed Comparisons with PHP 5.x and PHP 7

Figure 1: Speed Comparisons with PHP 5.x and PHP 7

If you’re doing professional development, you’ll want to wait until the official release of PHP 7 is out, but once it is, get yourself and your clients on a hosting service that supports PHP 7.

What Happened to PHP 6 : Abandonware

One of the questions asked at the presentation by Cal Evans was,

What happened to PHP 6?

I was thinking “vaporware” but that’s not fair nor accurate. Cal said that it was getting so on-off-on-off for a release, that it was simply abandoned to reduce confusion; so PHP 6 is “abandonware” but in fact about the only thing abandoned was the name. At the last minute one of the most important changes occurred when a huge speed improvement was introduced. Zend’s PHPNG (PHP Next Generation) engine is in head-to-head competition with HHVM (Hip-Hop Virtual Machine) from Facebook; so now with two engines competing for speed, let’s hope we all win in the speed of PHP. (Most of the speed data is from benchmarks based on the speed of numeric loops; so while speed is going to improve; don’t expect a rocket to the moon on most speed improvements.)

So What Effect Does this Have on OOP and Design Patterns?

From what I can tell; some affects to OOP may crop up, but not a lot as far as this blog is concerned. All of the examples on this blog have kept data typing strict: once a variable uses a data type, it doesn’t change. Likewise, type-hinting in parameters have forced only certain data types to be allowed in parameters. With PHP 7, type declarations are now available for scalar variables and return types. You should be able to add these declarations to any of the examples on this blog without an exception being thrown. All along we’ve been careful not to switch data types. One exception might be between integer and float types; so you might want to check there. Also, PHP 7 has a new integer divide function (intdiv()). The interval() function used up to this point will likely be replaced by the new intdiv() function where appropriate.

One of the new features that will definitely affect the way methods are written is the addition of return-type declarations. These work like the parameter declarations that have been used with object type (e.g., array, classes). So, for example, you can have something like the following:

<?php
class Infomaster
{
   private $members = 32;
   public function getMembers(): int
    {
       $groups=intdiv($this->members,5);
       return $groups;
    }
}
?>

The intdiv() function insures that the value will be an integer and the return type (int) is guaranteed. Throughout this blog, you should be able to use these kinds of type declarations without disrupting the code since care has been taken to be certain that everything is equivalent to a more strongly typed language.

What’s Next?

I’ve been waiting for the official release of PHP 7 before going ahead and finish my Sandlight CMS. This is for two reasons. My current Sandlight site is on a hosting service that is pretty far behind the curve in terms of current PHP and MySql. (e.g., I cannot use mysqli because their version of MySql is so out of date.) I’ve got to get a new hosting service, and unfortunately, the best one for what I want to do requires me to step up my IT Networking skills—get better at the command lines to work with installing PHP and the rest of LAMP files on a server that is basically carte blanche. Once I get to the point where I can program and develop, I’m good. It’s just the set-up that gives me the heebie-jeebies.

The other reason is that I want to use PHP 7 as a development language. I’m not going to worry about backward compatibility since I don’t have to support any lame web sites that some hacker built. Everything is going to remain both OOP with an increasing introduction of Functional Programming techniques that can be handled by PHP 7. I may use some Hack Language and install HHVM, but I prefer to use PHPNG with PHP 7. If I can, I’ll use both together. First, though, I have to go to the salt mines of the IT moles and get my system set up. Groan.

Share

Simple Functional Sniffer & Switch Alternative

mix Because PHP is a server-side language, you will have times that you need to rely on client-side languages like CSS, JavaScript and even HTML5 to accomplish certain tasks. In developing the CMS, I realized that while incorporating JavaScript, CSS and HTML5 in heredoc strings, I’d established a barrier between PHP and everything else by only allowing these other languages to interact with PHP through objects. Of course, this is because PHP has emerged into an OOP language and the others have not.

What I failed to take into account is the fact that it’s perfectly possible for OOP structures to interact with non-OOP structures. To some extend that has been done with HTML/CSS UIs and PHP design patterns in several examples. That seems to work out fine, but where you want to use dynamic variables for more responsive HTML pages, we’re back to encapsulating HTML (along with Javascript and CSS) into heredoc strings in PHP. There’s nothing wrong with that, and there’s much to be said for having a fully integrated OOP design pattern with a pure PHP engine.

A Simple Functional JavaScript Sniffer

The problem I discovered in a pure PHP design is that other design possibilities are overlooked. The primary style tool for HTML documents is CSS, and the media queries in CSS3 are designed to be responsive to different devices—namely, those brought about by mobile computing. Sometimes (and I do mean sometimes) that solution seems to work fine. Other, times, however, the media queries fail to capture that chunk of CSS3 code that formats for the desired device. On top of that, it can be difficult calling up certain jQuery mobile files—or any other files—from CSS alone. In many ways, libraries in jQuery have proven to be far more robust than CSS3 alone and far easier to deal with. In several respects, probably in most, neither CSS nor jQuery mobile are programming so much as they are styling tools. As such, they’re the tail of the programming dog. This is not to say they’re less important; they’re just not programming.

So, to sort out the devices looking at our pages, (moving away from CSS media queries) is a programming task. In several other entries on this blog, I’ve looked at ways to sniff through the possible devices, and I think we need to conclude once and for all that user-agents are next to useless. So, by exclusion, we’re left with screen width. So,begin by looking at this simple JavaScript sniffer using two lambda functions:

?View Code JAVASCRIPT
//Save as file name "jsniff.js"
var wide = screen.width;
var beta=function() {wide >=900 ? window.location.href="Desktop.html" :  window.location.href="Tablet.html";};
var lambda=function() {wide <= 480 ? window.location.href="Phone.html" : beta();};

In past posts I’ve used the Chain Of Responsibility (CoR) design pattern to do the same thing using either user agents (forget about it!) or width determined by a JavaScript object. The little JavaScript lambda functions do the same thing, and while at some point of granularity your may wish you had your CoR pattern, generally, I think that there’s enough with the three general categories at this point in time to deal with multiple device. Use the buttons to test the functions. (Try it with your phone and tablet too.) Click PlayA for the sniffer and PlayB for the PHP functional alternative to the switch statement. The download button downloads the source code for both.

PlayAPlayBDownload

The process is pretty simple both from a programming and a lambda calculus perspective. From lambda calculus we get following definitions of true and false:

true := λx.λy.x
false := λx.λy.y

As algorithms, we might consider the following:

function(x, y) {return x;};
function(x, y) {return y;};

So, that means:

function (10,20) = 10; ← true : Is 10
function (10,20) = 20; ← false : Not 10

That’s not exactly lambda calculus, but it’s along those lines that we can eke out an idea. (If you’re thinking, “What about function(10,10) that would appear to be both true and false,” you see what I mean.)

So now we’ll add the values a and b and reduce it:

((λx.λy.x) a b) -> ((λy.a) b) -> a

That replaces λx with (λy.a) b and then a. So a is a. Well, it sounds true!

Then for false we have:

((λx.λy.y) a b) -> ((λy.y) b) -> b

In looking at this, we see that if a is a its true; otherwise it’s b which is not true. That’s pretty much like if-then-else. If true a, otherwise it’s b.

So the line in JavaScript would be a ternary:

lambda = function(a) { return a ? a : b ;};

as well as in PHP,

$lambda = function($a) { return $a ? a : $b ;};

For now, that’s enough linking up lambda calculus with Internet languages. With our JS “sniffer” using a simple HTML call, we can get the page configuration we want for our device based on the window size:

<html>
	<head>
		<title>Functional Sniff</title>
			<script src="jsniff.js"></script>
	</head>
	<body onload=lambda()>
	</body>
</html>

Try it out. It’s easy to write and it’s practical. What’s more, you can see how close everything is to a Boolean type decision. (The different device HTML5 files are in the materials in the download package; one of which uses the jQuery Mobile formatting.)

I Don’t Need No Stinkin’ Switch Statement

One of the nice things about functional programming is that it made me re-think how I was programming. One of the areas where I thought I’d be able to boil down an algorithm to something more compact came when I decided to break down a calendar output into four weekly segment. Using a jQuery calendar, I could pick a day and pass the information to a PHP class for processing. Initially, the switch statement came to mind as a solution in something like the following:

$d=$this->numDay;
switch ($d)
       {
         case ($d >=1 && $d<=7):
            return "jquery";
            break;
        case ($d> 7 && $d<= 14):
            return "haskell";
            break;
        case ($d> 14 && $d<= 21):
            return "php";
            break;
        default: return "racket";
       }

In looking for a range, each case acts like a little function. So why not use lambda functions in PHP to do the same thing. Each query (case/function) either returns a value or goes on to the next case. Here’s what it looks like:

$gamma=function($d) {return $d > 14 && $d <= 21 ? "php" : "racket";};
$beta = function($d) use ($gamma) {return $d > 7 && $d <= 14 ? "haskell" : $gamma($d);};
$lambda = function($d) use ($beta) {return $d >=1 && $d <=7 ? "jquery": $beta($d);};
return $lambda($this->numDay);

The last used lambda function is the first in the list ($gamma). That’s because in order for the subsequent function to call them with the use statement, the function used must be defined before the one using it. In functional programming, the use of one function by another is referred to as a closure.

The Language Mix-Master

With the key parts in place, take a look at the different parts and languages used. First of all, the program begins with an HTML5 UI. It links to the jQuery UI JavaScript files and the CSS files. A further stylesheet links to the local CSS.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Datepicker - Default functionality</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
   <link rel="stylesheet" href="lang.css">
  <script>
  $(function() {
    $( "#datepicker" ).datepicker();
  });
  </script>
</head>
<body>
  <h2>Language of the Week</h2>
  <h4>Click in the text box to select from pop-up calendar: </h4>
 <form action="LangWeek.php" method="post" name="useUI" target="showpix">
<p>Date: <input type="text" id="datepicker" name="pick" /></p>
<input type = "submit" value="Get Language" />
</form>
 <iframe name="showpix" width="300" height="300"></iframe>
</body>
</html>

A form links to a PHP file where it passes the selected datepicker() value. The iframe tag provides a visual feedback embedded in the HTML page. (Note: Remember, with HTML5, iframes are no longer evil.)

Finally, using a single PHP class, the selected date is reconfigured to an integer and evaluated by the lambda functions described above in lieu of a switch statement:

<?php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
 
class LangWeek
{
    private $dateNow,$dayMonth, $numDay;
 
    public function __construct()
    {
        $this->dateNow = $_POST['pick'];
        $this->dayMonth=substr($this->dateNow, 3,2);    // Start 03  : 2Length
        $this->numDay = intval($this->dayMonth);
        echo "<img src='images/{$this->chooseLanguage()}' . '.jpg'>";
    }
 
    private function chooseLanguage()
    {
        $gamma=function($d) {return $d > 14 && $d <= 21 ? "php" : "racket";};
        $beta = function($d) use ($gamma) {return $d > 7 && $d <= 14 ? "haskell" : $gamma($d);};
        $lambda = function($d) use ($beta) {return $d >=1 && $d <=7 ? "jquery": $beta($d);};
        return $lambda($this->numDay);
    }   
}
$worker = new LangWeek();
?>

Fortunately the jQuery date picker passes the date as a consistent string mm/dd/yyyy, and so the only requirement is to use a substring to find the day of the month and convert it to an integer. This is passed to the chooseLanguage() method that employs the lambda functions.

Mixing it Up

While this blog is dedicated to PHP Design Patterns and their application, I believe that PHP programmers should explore beyond OOP and try out different kinds of programming within an OOP framework, which happily exists within a Design Pattern. The willingness to explore and experiment keeps programming fresh and interesting in any language.

Share

Sandlight CMS VI: Strategy Administrative Module

admin A CMS is only as good as the administrative module, and the one provided here is fully functional based on a simple work flow. You can change the UI and work flow to best fit your own, but you have the flexibility design patterns offer; so making changes to fit your needs (or those of your customers) should not be difficult.

One of the key features of a dynamic Web page is that it can be updated easily, and by using a MySQL table and database, all of the update information can be stored in a single location (table.) Updating the page is simply a matter of updating the data in a record or by adding new records to the table. The administrative module for this CMS has the capacity to update data in an existing record, but the page presented is always the newest record. The CMS has certain drawbacks because you cannot delete records without throwing the system out of whack, but that was done for the purposes of ease of use. (Remember, you’re a programmer and can change whatever you want!)

Set the Table

Setting up the MySQL table involves three files: 1) an interface with the MySQL connection information; 2. a connection class; and a table-creation class. The following three classes: (Use your own MySQL connection information in the IConnectInfo interface.)

< ?php
//Filename: IConnectInfo.php
interface IConnectInfo
{
	const HOST ="your_host";
	const UNAME ="your_username";
	const PW ="your_pw";
	const DBNAME = "your_dbname";
	public static function doConnect();
}
?>
 
< ?php
//Filename: UniversalConnect.php
ini_set("display_errors","1");
ERROR_REPORTING( E_ALL | E_STRICT );
include_once('IConnectInfo.php');
 
class UniversalConnect implements IConnectInfo
{
	private static $server=IConnectInfo::HOST;
	private static $currentDB= IConnectInfo::DBNAME;
	private static $user= IConnectInfo::UNAME;
	private static $pass= IConnectInfo::PW;
	private static $hookup;
 
	public static function doConnect()
	{
		self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
		try
		{	
			self::$hookup;
			//Uncomment following line for develop/debug
			echo "Successful MySql connection:<br />";
		}
		catch (Exception $e)
		{
			echo "There is a problem: " . $e->getMessage();
			exit();
		}
		return self::$hookup;
	}
}
?>
 
< ?php
include_once('IConnectInfo.php');
include_once('UniversalConnect.php');
class CreateTable
{
	private $drop;
 
	public function __construct()
	{
		$this->hookup=UniversalConnect::doConnect();
		$this->tableMaster="your_table_name";
		$this->dropTable();
		$this->makeTable();
		$this->hookup->close();	
	}
 
	private function dropTable()
	{
		$this->drop = "DROP TABLE IF EXISTS $this->tableMaster";
 
		try
		{
			$this->hookup->query($this->drop) === true;
			printf("Old table %s has been dropped.<br />",$this->tableMaster);
		}
		catch (Exception $e)
		{
			echo "Here is why it did not work:  $e->getMessage() <br />";
		}
	}
 
	protected function makeTable()
	{
		$this->sql = "CREATE TABLE $this->tableMaster (
			id SERIAL,
			topic NVARCHAR(24),
			header NVARCHAR(120),
			graphic NVARCHAR(60),
			story BLOB,
			PRIMARY KEY (id))";
		try
		{
		  $this->hookup->query($this->sql);
 
		}
		 catch (Exception $e)
		{
			echo 'Here is why it did not work: ',  $e->getMessage(), "<br />";
		}
		echo "Table $this->tableMaster has been created successfully.<br />";
	}
}
 
$worker=new CreateTable();
?>

The connection routines have been improved upon over time, and you can find out more about it in the original post on the subject on this blog. For now, Play the application and Download the source files. (When you click the Play button, you enter the Login UI. Use the same un/pw combination from the Functional Protective Proxy post on this blog. (Hint, you can find it in the ILogin abstract class.)
PlayDownload

In creating the table at first I used the TEXT data type for a large block of text, but then decided that a BLOB type may have a slight advantage. The BLOB is a VARBINARY and TEXT is VARCHAR, and BLOB seemed to have a slight advantage. However, the advantage may be smaller than I originally thought. Check out the MySQL docs on these two data types and you can see the differences for yourself. Figure 1 shows what the editor in the administration module looks like:

Figure 1: Administrative Module Editor

Figure 1: Administrative Module Editor

From Proxy to Strategy

The login module of this CMS is based on the Proxy pattern. Now, as in previous CMS examples, the administrative module is based on a Strategy pattern. Each object in the Strategy pattern represents an algorithm to accomplish a different task. In this case, the tasks include:

  • Entering data
  • Editing data
  • Displaying data
  • Displaying a page based on stored data.

All requests go through a context relying on a Strategy interface. In this case, I used an abstract class which allowed the addition of several protected properties and a constant with the name of the table. This is all in addition to the main method in an abstract public function, the algorithm method, executeStrategy(). Following the Strategy design pattern, begin with the Context. Continue reading ‘Sandlight CMS VI: Strategy Administrative Module’

Share