Sandlight CMS III: PHP Abstract Factory

abfacNote: This is the third in a series for developing a CMS for Sandlight Productions. Drop by the Sandlight site to see the progress so far, and be sure to check your country’s flag count!

Now that the CMS has a filter for different devices, it now needs a pattern to take care of those devices and different types of content that they will display. Previous posts on this blog used the Bridge pattern and the Factory Method pattern. However, another pattern might be more useful for all of the different things that a Content Management System (CMS) might do. A review of the series of posts on this blog for how to select a design pattern, shows the different criteria to consider. The CMS has to create different elements of a Web page for different devices and that fact must be the focal point of the consideration. The section head for Creational Patterns in Learning PHP Design Patterns, lists the Abstract Factory pattern as a creational one, but that pattern was not discussed in the book nor on this blog. It would appear to be just what this CMS needs.

The Abstract Factory Design Pattern

The Abstract Factory pattern has features for families of factories and products instead of individual factories as does the Factory Method pattern. In comparing the relatively simple Factory Method pattern with the Abstract Factory, the Abstract Factory has multiple abstract product interfaces with multiple concrete factories for the families of the products.

Figure 1 shows the the Abstract Factory class diagram, and when you look at it, try to focus on the fact that the pattern has two types of interfaces: Factory and Product. So, if you understand the Factory Method pattern, you have a starting point for appreciating the Abstract Factory:

Figure 1: Abstract Factory class diagram

Figure 1: Abstract Factory class diagram

Unlike the Factory Method pattern, the Abstract Factory includes a Client class as an integral part of the pattern. Further, the Client holds an association between both the AbstractFactory (AbsFactory) and the two AbstractProduct classes. So while it shares some of the basic Factory Method characteristics, it is clearly a different pattern than the Factory Method.

Since the Abstract Factory may appear to be daunting, the color-coded the product instantiations (dashed lines) in the file diagram (appearing in the Play window) help show where each concrete factory method calls. Experiment with different combinations of factories (devices) and products (page parts) and look at the diagram so that you can see the path. Phone instantiations are in green, Tablet in red, and Desktop in blue. Experiment with the different single products first, and then click the bottom button to see what different “pages” each device factory displays.

Implementing the Abstract Factory in PHP

To see how this implementation of the Abstract Factory design pattern works, click the Play button. You will see both the interactive Abstract Pattern tester and the of the file diagram of this implementation of the Abstract Factory for the evolving Sandlight CMS. Click the Download button to see all of the files in the diagram. For this particular post, downloading all of the files is more important than usual because there are lots of them, and rather than having listings for all in this write-up, I’ve just selected representative ones.
PlayDownload

In addition to the Abstract Factory file diagram (viewed when you click the Play button), the following quick overview of the participants’ roles and how the CMS implements the Abstract Factory explain how this implementation works:

Client client: Only uses interfaces declared by IAbFactory (interface) and IProducts (abstract classes IHeaderProduct, IImageProduct and ITextProduct.) This means that the Client can only use the classes and methods implemented from those two interface types—factory or products. In other words, it should not directly implement a product (a page element) by directly using a product independent of the factory and product interfaces. Figure 2 illustrates this point:

Figure 2: Client works through Abstract Factory implementations

Figure 2: Client works through Abstract Factory implementations

In going over the other participants below, keep in mind that the Client can only implement concrete implementations of the IAbFactory to request products (page parts for different devices.)

IAbFactory interface: Establishes the methods for the concrete factories.

  • PhoneFactory implements operations to create phone products
  • TabletFactory implements operations to create tablet products
  • DesktopFactory implements operations to create desktop products

IHeaderProduct: abstract class Establishes the method for concrete header products and adds protected property for returning completed product.

  • PhoneHeader defines phone object to be created by the PhoneFactory and
    implements the IHeaderProduct interface
  • TabletHeader defines tablet object to be created by the Tabletactory and
    implements the IHeaderProduct interface
  • DesktopHeader defines desktop object to be created by the DesktopFactory and
    implements the IHeaderProduct interface

IImageProduct: abstract class Establishes the method for concrete image and/or video products and adds protected property for returning completed product.

  • PhoneImage defines phone object to be created by the PhoneFactory and
    implements the IImageProduct interface
  • TabletImage defines tablet object to be created by the Tabletactory and
    implements the IImageProduct interface
  • DesktopImage defines desktop object to be created by the DesktopFactory and
    implements the IImageProduct interface

ITextProduct: abstract class Establishes the method for concrete text products and adds protected property for returning completed product.

  • PhoneText defines phone object to be created by the PhoneFactory and
    implements the ITextProduct interface
  • TabletText defines tablet object to be created by the Tabletactory and
    implements the ITextProduct interface
  • DesktopText defines desktop object to be created by the DesktopFactory and
    implements the ITextProduct interface

Comparing the above outline with the Abstract Factory file diagram (seen when you click the Play button) shows that the Abstract Factory is bound to the idea of a factory implementing a product. The specific classes (products) requested are never directly referenced by the Client; rather it is through a factory. The CMS application requires factories for the different device categories; Phone, Tablet and Desktop. Each factory should be able to build the necessary parts (products) for each device. In this case (and for this example) the products are a Header, Graphic and Text. Each factory can build its own version of the products; so requesting a header, for example, is through a concrete factory, and depending on which concrete factory the clients requests, it builds the appropriate product.
Continue reading ‘Sandlight CMS III: PHP Abstract Factory’

Share

Sandlight CMS II : Mobile First!

mobileFirstI’m not a graphic designer, and so I depend on others for the graphic elements and arrangement of my Web pages. However, I strive to make a site that is clear, easy to understand and useful. My focus is on good user experience (UX) and information design—clear communication with the user. In order to have good UX, you need to know something about Responsive Web Design (RWD), and if you don’t, check out the RWD link. Further, if you are unfamiliar with the approaches to RWD, I’m sold on the Mobile First approach, but possibly for different reasons than designers. Let me explain.

In designing my own site, my focus is on content categories, ease of maintenance, which includes updates and changes, and device flexibility. So I have to keep all of those in mind. I want PHP to handle regular updates by using content from a MySql database (the Content Management of CMS), and I need it to work on different devices. By tackling mobile first, I have to create a diamond-tipped focus on exactly what I want the user to view because even with the new “Phablets,” I’m not dealing with a lot of screen real estate. Currently, my old working mobile phone has a CSS resolution of 320 x 480, and my Phablet is 414 x 736. That’s less that 100 units different. (By CSS resolution, I’m referring to what CSS reads as far as screen width is concerned. See this table.)

Choosing the Devices

In an another sniffer program using a Chain of Responsibility (CoR) design pattern and a PHP user agent ($_SERVER['HTTP_USER_AGENT']) posted on this blog, the sniffer detected the user agent and then found the handler responsible for that agent. Now that user agents have been replaced by CSS screen width (as determined by a JavaScript function) for determining the device, we can use the same CoR pattern making the necessary changes. However, instead of getting real pages, we can use stand-ins that only have the roughest page content. All of the content will be encapsulated into PHP classes using heredoc strings. Near-future posts cover the mechanics of working out the MySql to provide dynamic content for the pages, along with other details necessary for the CMS. For now, though, the dummy pages will only contain enough material to demonstrate that each is appropriate for the selected device. Use the buttons below to see the current state of the CMS and download the files for this portion:
PlayDownload

Note that all devices can now access the Flag Counter. Where is your country on the Flag Counter? (See the note about the Flag Counter at the end of this post.)

Back to the Chain of Responsibility Pattern (CoR)

The CoR pattern is handy because it’s easy to update and change. For example, suppose that having three device categories (e.g., phone, tablets and desktops) proves to be inadequate and you want to add two more; one for laptops and another for phablets. It’s a simple matter to add to the chain and add device classes to handle the new devices. Figure 1 shows the first design pattern to be used in the CMS:

Figure 1: Chain of Responsibility Implementation

Figure 1: Chain of Responsibility Implementation

In Part I of this series, you can see how the device width and height is determined using a JavaScript closure (object) to pass the information to HTML and on to PHP. Since we only need to find the width, the JavaScript code has been slightly altered and placed in a separate file (deviceCatcher.js) in case it needs to be reused.

?View Code JAVASCRIPT
//deviceCatcher.js
function getWide()
{
	var wide = screen.width;
	return function()
	{
		return wide;
	}
}
var w = getWide();
//Send data to PHP class, CoRClient.php	
var lambdaPass= function() {window.location.href = "CoRClient.php?hor=" + w();};

The HTML file simply calls the closure function which passes the values to PHP:

<html>
	<head>
		<title>Device Catcher</title>
		<script src="deviceCatcher.js" type="text/javascript"></script>
	</head>
	<body onload=lambdaPass()>
	</body>
</html>

The HTML file is a trigger to get the ball rolling with the client class (CoRClient).

Starting the Chain

The client pulls the viewing device’s width from the superglobal, and passes it to a PHP variable. Given the variability in the width of device screens, I made the decision to work with three sizes to get started: 1) phone, 2) tablet, and 3) desktop. So, depending on the width, the request would be handled by one of those three device groups. I used the following cutoff sizes:

  1. Phone: >= 480
  2. Tablet: >=481 and < 900
  3. Desktop: >= 900

I used this table as a guide, but cutoff points can be anything you want.

Getting the width from the superglobal is easy enough using a static variable:

self::$wide=$_GET['hor'];

The, using the cutoffs, the program needs to generate three strings, phone, tablet, and desktop to send to the Request class that stores the appropriate string. The most obvious way is to use conditional statements (if or switch) to generate the correct string for Request. For example an imperative algorithm such as the following would do the trick:

if(self::$wide < = 480)
{
	return "phone";
}
elseif (self::$wide >= 900)
{
	return "desktop";
}
else
{
	return "tablet";
}

However, a functional program would be more compact, and like the JavaScript closure used in Part I, it would be an “object.” Transformed into a functional closure, the operation would look like the following:

$beta = self::$wide >= 900 ? 'desktop' : 'tablet';
$lambda = function($x) use ($beta) {
	$alpha =  $x < = 480 ? 'phone' : $beta;
	return $alpha;};

Using ternary operations ?: , $alpha and $beta both have function-like qualities. for example, $beta could have been written as a function beta() as shown in Figure 2:

Figure 2: "Functional" variables

Figure 2: “Functional” variables

As you can see in Figure 2, $beta provides the same functionality as beta(), and $beta can be used as a reference in the $lambda function along with $alpha in a PHP closure. (For some reason, when $beta is assigned an anonymous function, I was unable to get it to be added as a closure in the $lambda anonymous function.)
Continue reading ‘Sandlight CMS II : Mobile First!’

Share

Sandlight CMS I: Device Closures

devicesIn previous posts on this blog, I’ve included PHP patterns that deal with the issue of creating sites for multiple devices. In developing a Content Management System (CMS) for my Sandlight site, I wanted to start from scratch and use both elements of OOP and design patterns as well as functional programming. (Functional programmers may furrow their collective brows and mutter You’re ruining FP, but there’re enough arguments among FP advocates, that I’m not overly concerned.)

The Problem with User Agents

The problem with user agents (UAs) such as $_SERVER['HTTP_USER_AGENT'] in PHP, is that the information they provide is insufficient. For example, if you get “trident” from a user agent, it could be anything from a Microsoft-based computer to a MS phone. Devices identified as “iPad” can be the iPad Minis or the full-size iPads. And of course, if you get “Android” or “iPhone,” it can be any size screen from the early smart phones to what some call “Phablets”— the big phones like iPhone 6+ and Galaxy Note 3. To get started, take a look at this table. Not only will that table give you a range of mobile devices, it provides the way in which browsers communicate the type of device currently reading a page. (The CSS column is the most relevant for setting up a CMS that will adjust to different devices.)

How Can You Get the Screen Size for PHP?

If you’ve used CSS3, you are familiar with CSS media queries where you can direct the CSS to different classes and IDs depending on the screen size. It’s just as easy using JavaScript. The built-in document properties, screen.width and screen.height can be passed to variables and in turn to PHP. The procedure is a simple one-line program:

<script>
  window.location.href = "WiHi.php?hor=" + screen.width + "&vert=" + screen.height;
</script>

The JavaScript variables are hor and vert and can retrieved in PHP using $_GET[‘hor’] and $_GET[‘hi’]. So while that code can be saved as an html file and pass the data to a PHP class, it also offers up an opportunity to demonstrate how to add functional programming (FP) to JavaScript and to use FP with OOP. Use the buttons to test the program on as many devices as you have to see the range of screen sizes. Download the complete file set as well:
PlayDownload

Instead of stopping here and announce Mission Accomplished, I’d like to consider functional programming in JavaScript and closures in particular. In order to understand why I think it’s important to do this, consider the general purpose of both OOP design patterns and functional programming. Both were developed to better organize programming so that larger programs (consider what goes into your favorite game program) can be developed, maintained and changed.

Hackers vs Programmers

Hackers and hacks have a history of unthoughtful and malicious programming. It takes talent to build a house, but none to burn one down. The term “hack” originated as a program created by programmers who just threw code at a problem until something worked. The problem with hacks and hackers is that while the short-term goals may be accomplished, especially with short programs, hacks are like a guy with a machete chopping his way through the jungle to make a trail. The next time he comes down the trail, it’ll be grown over, and he’ll have to hack a new path. Figure 1 illustrates creating a hack vs. creating a program:

Figure 1: Hacking vs. Programming

Figure 1: Hacking vs. Programming


Compared to a modern highway, where planning, use of structure and interactive cooperation can create something of lasting value, hacks are a one-time accomplishment. It’s a kid playing in the mud. Fun until he’s got to start cleaning his own clothes.

Functional Programming in JavaScript

As you probably know, JavaScript does not have classes per se, and so we’re not going to try to create an OOP class in JS. However, the JavaScript folks are fortunate in having the book, Functional JavaScript (O’Reilly, 2013) by Michael Fogus. Functional programming is an important framework to understand in both PHP and JavaScript, and you can find a number of articles and other works covering FP in JS in addition to the Fogus book.

The “objects” in FP are called closures. In variations on JS and in special FP libraries (e.g., Underscore.js) you can find more FP functionality just as in the Hack dialect of PHP has functional operations for PHP not found in standard PHP. However, for here, I’d like to stick to plain vanilla JS and create what Fogus referred to as a “closure simulators” (faux closures), but they serve the same purposes. (PHP also has closures and a built-in Closure class.) I tend to think of closures as FP “objects,” but that characterization has a number of fuzzy edges; however, it’s a convenient way to think about them. Fogus summarizes a closure

as a function that captures the external bindings (i.e., not its own arguments) contained in the scope in which it was defined for later use (even after that scope has completed.)

—Michael Fogus p. 60, Functional JavaScript (O’Reilly, 2013)

A bit more dramatic description by Fogus is,

Closures are the programming language equivalent of vampires—they capture minions and give them everlasting life until they themselves are destroyed. The only difference is that closures don’t sparkle when exposed to sunlight.
—Michael Fogus p. 61, Functional JavaScript( O’Reilly, 2013)

Unfortunately, the PHP manual describes closures as equivalent to anonymous functions or lambdas. Simon Holywell in Functional Programming in PHP (p. 33) clarifies the manual’s misconception by noting that PHP closures are functional structures that include the use clause. In any event, both Holywell and Fogus describe a type of “object” where data can be packaged and used elsewhere in a program. So let’s take a look at a closure in JavaScript:

<html>
	<head>
		<title>Passing Width & Height with Closure</title>
		<script type="text/javascript">
			//Use closure "objects" to store screen size
			function getWide()
			{
				var wide = screen.width;
				return function()
				{
					return wide;
				}
			}
			function getHi()
			{
				var hi = screen.height;
				return function()
				{
					return hi;
				}
			}
 
			//Pass closures to variables
			var w = getWide();
			var h = getHi();
 
		        //Send data to PHP class, WiHi.php	
			var lambdaPass= function() {window.location.href = "WiHi.php?hor=" + w() + "&vert=" + h();};
		</script>
	</head>
	<body onload=lambdaPass()>
	</body>
</html>

The two functions, getWide() and getHi() are simulated closures, but functionally, they work just like closures. In fact, they work pretty much like objects. These two closures are passed to variables, w and h, which themselves are then closures and can be used to return the width and height of the device screen. Continue reading ‘Sandlight CMS I: Device Closures’

Share

Is PHP an OOP Gateway Drug?

gatewayIs OOP in PHP going to Help in Other Languages?

PHP is a great tool for working with both Web-based languages like HTML5, JavaScript, CSS3 and jQuery (actually a kind of JavaScript). Of course it’s an essential tool for working with SQL and the kinds of server-side operations that can only be done with a server-side language like PHP.

With the advent of mobile devices, PHP developers are able to add to help recognize devices through user-agents, but sniffers are plagued by both the vague information provided by the user-agents and may not be able to tell the difference between different screen widths and resolutions with the same user-agent information; like iPads and iPad Minis. Microsoft has the same user-agent id for all of their devices–“trident.”

Web Apps and Device Apps

PHP has been a great tool in Web app (applications that run in a browser) development for mobile devices, but these apps are largely dependent on an Internet connection, and unless there’s some way to add a local host to an Android-based Note or iOS-based iPhone, you rely on a connection to the Web. Even with WiFi being widely and generally available, an app that runs on the native Android OS or the Apple iOS (Device App) has lots of advantages over a Web app.

Don’t get me wrong. Web apps have tons of advantages over device apps when it comes to development and distribution. All devices that have browsers can run Web apps, but apps made for an Android will not run on iOS devices and vice versa.

So if you know PHP (and lots of other Internet languages), at some point you may have to bite the bullet and download the (free) Android and/or iOS SDK (Software Development Kit). The good news is that if you’ve been working with PHP OOP and design patterns, much of the code environment will look very familiar. The IDEs used by both the Android and iOS SDKs are very similar. The development process, though, takes place within classes and structures that you will be familiar with—depending on how much you’ve been experimenting with PHP OOP and design patterns.

For example, the following is a simple Swift class that generates a message—not too dissimilar from what JavaScript does with an alert() function.

import UIKit
 
class ViewController: UIViewController
{ 
    @IBAction func showAlert()
    {
        let alert = UIAlertController(title: "Sandlight Productions, LLC",
            message: "Messages for the World!",
            preferredStyle: .Alert)
 
        let action = UIAlertAction(title: "Sandlight", style: .Default, handler: nil)
 
        alert.addAction(action)
 
        presentViewController(alert, animated: true, completion: nil)
    }
 
}

Both the Android and iOS SDKs have lots of importable classes, and the imported UIKit has objects for the UI. The class declaration,

class ViewController: UIViewController

would be like declaring

class ViewController implements UIViewController

in PHP. So, while some different operators are used (e.g., : instead of implements) most of the statements are pretty close to those in PHP.

Some, though, are special to both the framework and the language. For instance,

@IBAction func showAlert()

does not have an equivalent in PHP for the whole method. The @IBAction connects the source code to a UI object. The showAlert() method, in this example, is connected to a button in the Interface Builder, part of the iOS SDK. Further, func is used instead of function used in PHP.

In declaring variables, Swift, uses the let keyword and the = assignment operator, and Swift does not use the new keyword in creating objects. For example, in Swift,

let alert = UIAlertController(//parameter list);

would be,

$alert = new UIAlertController(//parameter list);

in PHP. If you understand something about OOP and design patterns, this other type of programming makes more sense than if you do not.

Figure 1 shows the output on a simulator developed in the iOS SDK:

Figure 1: Landscape view of the alert in an iPhone 5s simulator.

Figure 1: Landscape view of the alert in an iPhone 5s simulator.

In and of itself, it’s no great shakes. However, it can be run anywhere and without a browser or an Internet connection. What’s important is that those working with OOP and design patterns in PHP are far closer to the languages used for Android (Java) and iOS (Swift). So if you start getting clients who demand to have their own apps to be downloaded to their phones and used without a browser, don’t be afraid to start making some simple ones. You can even create a device app that calls up a mobile app written in PHP and jQuery Mobile. The big advantage of that is you can access an SQL database.

Event Driven Programs and Programming: Not So Much PHP

If you’ve ever made a game—especially the arcade type—you’re probably familiar with “event-driven programming.” Languages like ActionScript, including OOP and design pattern designs, used to be used a lot in event-driven software development. The State design pattern is often used for event-driven programs since the states keep changing with new information from the user. The events are typically made up by the user tapping, sliding and dragging objects on the screen. PHP at some base is more of a data-getting and setting type of software. The getting and setting is done in conjunction with MySQL and the SQL language.

A lot of mobile app development is done with event-driven processes, and at least in the SDKs for iOS and Android, the frameworks are set up in classes and more state-like programming than you’ll see in most PHP. However, on this blog, the Client-Request model is easily applicable to event-driven kinds of applications. A number of PHP programmers have some interesting suggestions for event-driven programming and programs, but I’m not sure how well they’d work compared to languages like Python where the connections to the event-producing object (e.g., mouse/finger clicks/taps and keyboard entries) are more direct. PHP is a bit too dependent on HTML and JavaScript to handle events in client-side events.

In any event, using OOP and design patterns in PHP is very transferrable to other languages. The same is true in using the logic and structure of functional programming. So, if you’re thinking about jumping into either iOS or Android app development, you’ve be entering a familiar programming environment if you understand working with OOP and design patterns in PHP. Don’t be afraid of event-driven programs even though they’re not exactly common in PHP. The structures you will work in will be very familiar.

Share

PHP Command Design Pattern: Part I

commandEncapsulate a Request

On occasion when developing an application, you may want to issue a request, but you may not know about the requested operation or its receiver. Imagine that you’re developing a game, and you’re working on a “Commander” (like Captain Kirk of Star Trek). The commander will issue commands, but during development or execution, you’re not sure who’s going to carry out the command or exactly how it’s going to be done. For instance, suppose that a Weapons Officer on the bridge simply pushes a button when the Captain issues a command to fire a photon torpedo. However, suppose that the bridge is damaged and the Weapons Officer wounded and cannot carry out the command. Any decent game designer would allow for someone else to launch the torpedoes; a crew member working in the torpedo bay, for example. Therefore, you would not want to tightly couple the action of firing a photon torpedo with the Weapons Officer. Something like;

weapons_officer->firePhotons()

would not be a good idea. Instead, you’d want the request to be handled by anyone who could get to the torpedoes triggering mechanism—no matter who it was or what triggering device was employed.

The Command design pattern encapsulates the request as an object, and allows you to add parameters to the clients with different requests. You can also support undoable operations—like firing off a photon torpedo! In this particular example, the participants and implementation is quite simple. I employed a helper class (Move) to add a little flair to the example, but otherwise, it’s a very simple implementation of the Command design pattern. Fire off the torpedo and download the files to get started:
torpedoDownload

The movement operations were taken from an earlier post on this blog of working with SVG files—once again illustrating the re-use functionality of OOP design. The helper class, Move is almost wholly a re-use of the earlier implementation. The sound was added to the class for this example.

The Wholly Involved Client

The requesting client is fully involved in the Command pattern. It is associated directly with both the Receiver and the ConcreteCommand classes. Figure 1 shows the pattern’s class diagram:

Figure 1: Command class diagram

Figure 1: Command class diagram

In this example, I employed a single Client, Receiver, Invoker and ConcreteCommand. Largely, I re-purposed an abstract example that Chandima Cumaranatunge had used in ActionScript 3.0 Design Patterns that we had co-authored in 2007—the main difference being that the example is written in PHP and I added an action that involved sound and animation. However, it is largely the same. In looking at the code in the Client, you can see that it creates instances of a ConcreteCommand, Receiver and Invoker.

<?php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
// Autoload given function name.
function includeAll($className)
{
    include_once($className . '.php');
}
//Register
spl_autoload_register('includeAll');
 
/* Client */
class Client
{
    public static function request()
    {
        $rec = new Receiver();
        $concom = new ConcreteCommand($rec);
        $invoker = new Invoker();
        $invoker->setCommand($concom);
        $concom->execute();
    }
}
$worker=Client::request();
?>

As you can see, the Client, chooses the concrete command and the invoker. Figure 2 shows the file diagram for this Command implementation:

Figure 2: Command file diagram

Figure 2: Command file diagram

This pattern can have different commands and different invokers, but the key lies in the Command interface (ICommand) that includes an execute() method that invokes the command. It doesn’t concern itself with what other object does the invocation; it just provides the interface for some object to carry out the command.Using the bare minimum, the interface has a single abstract method:

<?php
interface ICommand
{
   function execute( );
}
?>

The design allows for a number of different ConcreteCommand classes, especially flexible because of the simplicity of the interface. However, in this example, only a single concrete command implements the interface.

<?php
class ConcreteCommand implements ICommand
{
    private $receiver;
    function __construct(Receiver $rec)
    {
        $this->receiver = $rec;
    }
    public function execute()
    {
        $this->receiver->action();
    }
}
?>

The receiver has been identified by the Client and passed to the parameterized ConcreteCommand by the Client. The Client acts very much like a conductor in this pattern. It pulls a the pieces together and determines how they will interact together. All of the work is to carry out the command realized in the Receiver class.

The Invoker Makes it Happen

Returning to the Star Trek example where the Captain commands the Weapons Officer to “fire a photon torpedo,” the Weapons Officer is the invoker. That is, by pressing the Fire button, she executes the command. However, as we noted, maybe the Weapons Officer is unable to carry out the order because she has been knocked out in a battle, and so someone else has to do it. Because the command and the invocation of the command are loosely coupled, any available invoker could carry out the command. First, take a look at the Invoker class:

<?php
class Invoker
{
    private $currentCommand;
    public function setCommand(ICommand $c)
    {
        $this->currentCommand = $c;
    }
    public function executeCommand()
    {
        $this->currentCommand->execute();
    }
}
?>

Note that both a method for setting the command and one for executing the command are part of the Invoker class. The Client sets the command, but how is it executed? Again, it is the Client, but the execute() method is through the ConcreteCommand instance; also called by the Client.

The Receiver Knows What to Do

In order for the command to be carried out, at least one object needs to do what the command requires. In this case, it’s the Receiver. Following the path so far:

  1. The Command tells what to do.
  2. The Invoker tells an object to carry out the command
  3. The Receiver carries out the requirements of the command.

Keep in mind that all of this is done with loosely coupled objects, and different participants can carry out the different roles.

<?php
class Receiver
{
   private $speed;
   private $photon;
 
   public function action()
   {
         $this->speed= 20;
         $this->photon = 16; 
         $launcher=new Move();
         echo $launcher->setVelocity($this->speed,$this->photon);
   }
}
?>

I suppose this is a bit elaborate for an abstract example, but it seemed a little more illustrative with something other than an echo statement that the Receiver object announced. Besides, it illustrates re-use of a class as a helper class for the Receiver to do a bit more. As you can see from Move helper class, a the property IDs from the original use have been retained—e.g., ‘ship’ and ‘torpedo’ used for the same purpose.

<?php
//Helper class
class Move
{
   private $velocity;
   private $capacity;
 
   public function setVelocity($speed,$ship)
   {
      $this->velocity=$speed;
      $this->capacity=$ship;
 
      $ship =<<<SHIP
      <!DOCTYPE HTML>
      <html>
         <head>
         <script type="text/ecmascript">
           // Single global variable
           var photon = 0; // Photon torpedo x position.
 
           function drawSVG()
           {
             //Interval Timer loop
             moveLoop = setInterval(fireTorpedo, $this->capacity);
           }
 
           function fireTorpedo()
           {
             // Change the photon torpedo's position
             photon += $this->velocity;
             photon = photon % 500;
             phpton.setAttribute("x", photon);
           }
         </script>
         </head>
           <body onload="drawSVG()">
             <!-- Create the SVG galaxy. -->
             <!--<?xml version="1.0" standalone="no"?> -->
             <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
               <svg width="500" height="200" viewBox="0 0 500 200"
                  xmlns="http://www.w3.org/2000/svg" version="1.1">
                 <desc>Oopz</desc>
 
                 <!-- Show outline of 2D Galaxy using 'rect' element -->
                 <rect x="0" y="0" width="500" height="200"
                     fill="navy" stroke="blue" stroke-width="1"/>
                 <!-- Space craft Oopz -->
                 <rect x="100" y="100" width="30" height="20"
                     fill="yellow" stroke="#369" stroke-width=".4" id="phpton" />
               </svg>
               <audio autoplay>
                  <source src="photon.ogg" type="audio/ogg">
                  <source src="photon.mp3" type="audio/mpeg">
               </audio>
       </body>
       </html>
SHIP;
      return $ship;
   }
}

You can revise the actions of the Receiver to virtually anything you want. The important point with the Command class is that the original command (request) is encapsulated through the ICommand interface, and in the development process there can be any number of different requests fulfilled by different receivers and launched by different Invoker objects. Further with added commands, you can also add new invokers and ever receivers.

Beyond Abstract Command Structures

Even though this example has not been quite as abstract as originally planned, it is still pretty basic. What I’d like to do in subsequent examples is to build on this basic pattern where multiple commands, invokers and receivers work in concert through the Command design pattern. In the meantime, feel free to try out some of your own ideas and offer suggestions for further improvement and/or refinement.

Share