Tag Archive for 'beginning PHP design patterns'

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

PHP Memento Design Pattern Part I: Wide & Narrow Interfaces

mementoWhere’s the Interface?!

In going through Design Patterns: Elements of Reusable Object Oriented Software I found only three design patterns with no abstract class or interface parents: The Singleton, The Facade, and The Memento. I quit using the Singleton after several articles and even Erich Gamma said it caused more problems than it solved, and I have not had an occasion to use the Facade in a practical application (yet). However, I used the Memento pattern in the development of a script that controlled a streaming video. When the user decided that he/she wanted to remember a certain part of the video, the Memento would save the position of the video and would go back to that position if requested. The purpose of the Memento is to capture an internal state and store that state in an external object. It is the ultimate “un-do” pattern. You can save any given state, store it and then go back to it using the Memento design pattern.

Ironically, the major concepts to understand in Memento development are those of wide and narrow interfaces. Further, the Gang of Four note that this may be tricky with languages that do not support two levels of static protection. (As far as I know, PHP does not have that support, but I’ve developed a workaround that does the trick.) So, without further ado, let’s take a look at the Memento. Run the program and download the files if you’d like:
PlayDownload

Saving State

The task of saving state is as simple as saving certain property values in a variable or array. For example, if you’re keeping score in a game, generally you just increment or decrement a variable. At some point you may wish to save a score and later on use it again. Let’s say that if a player reaches 100, you want to record that so that it can be used later in determining his/her character status. The Memento will do that for you and store a given state in a separate object, and the trick is to capture and retrieve that state without breaking encapsulation.

Without violating encapsulation, capture and externalize and object’s internal state so that the object can be restored to this state later.(GoF p. 283)

Figure 1 is the class diagram for that process:

Figure 1: Memento Design Pattern

Figure 1: Memento Design Pattern

It looks pretty simple, but it’s easy to get wrong, and if you look around on the internet, you’ll find plenty of bad examples. So let’s start with wide and narrow interfaces. (I thought you said it didn’t have interfaces!)

Wide and Narrow Interfaces

In most class diagrams, we will see a Client class—if not in the original class diagram, I generally put one in to use as a starting point. However, with the Memento, the Caretaker makes a request for a Memento from the Originator; so it acts like a Client. The Caretaker is supposed to act pretty much like a warehouse—it stores Memento objects, but it doesn’t alter their states. Then, upon request, it returns them.
Continue reading ‘PHP Memento Design Pattern Part I: Wide & Narrow Interfaces’

Share

PHP Prototype Design Pattern Part I: How to Clone

cloneClone My Instance

The Prototype Design Pattern is a creational one that I’ve been warming up to lately. Basically, the purpose of the Prototype pattern is to reduce the cost of instantiating objects through the use of cloning. So, the first thing we need to do is to understand how to use cloning in PHP and what it does.

Fortunately, PHP has a __clone() function built right into it, and it makes creating a Prototype design pattern a lot easier than languages where you have to write your own clone function. So, this post will just look at how the __clone() function works and how it saves resources in programming.

Before we get going, go ahead and play the example (and meet the lovely Ada Lovelace) and download the source code:
PlayDownload
Take a look at the listings, and you’ll see where the __clone() function is located. Also, see how it is used to create a cloned instance.

A Class with a Clone Within

To clone an object in PHP, you need to create the Class you plan to clone with the __clone() function inside. So for ClassA to be cloned by $objectB, I need to include the __clone function inside ClassA. The instantiation process would look like the following:

$objectA = new ClassA();
$objectB = clone $objectA;

To get started, then, we’ll need to create a class that contains a __clone() function. This will be an abstract class, and the __clone() function will be abstract as well.

< ?php
//CloneMachine.php
abstract class CloneMachine
{
	protected $designation;
 
	public function showHelp($designate)
	{
		$this->designation=$designate;
 
		echo "<img src='ada.png'/>";
		echo "<br />$this->designation <p></p>";
	}
	abstract function __clone();
}
?>

Continue reading ‘PHP Prototype Design Pattern Part I: How to Clone’

Share