Tag Archive for 'choosing PHP design pattern'

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 , 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:

?View Code HTML

        
                Device Catcher
                
        
        
        

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!’

PHP Near Strategy Design Pattern Part I: No Conditionals, Please

nearStratWhy ‘Near’ Strategy?

The Strategy design pattern is important because it is so useful, and two different posts on this blog have covered it in the past. What I would like to do with this implementation of the pattern is to do two things: 1) First, show how to create operations that require no conditional statements, and 2) Second, (in Part II) show the role of the Context participant. In this first part, I’d like to look at the HTML->PHP operations where specific objects (classes) can be called through HTML forms.

One of the nice things about the Strategy pattern is that the logic of it is very easy to understand; albeit on a foundational level. You have different tasks, and each task requires a different algorithm; so why not separate the algorithm operations into distinct objects (classes) and loosely bind them to the client? Each class will only do one thing, and that is to carry out an algorithmic operation. To do this, start off with a “Near Strategy”–a pseudo-patten: the Strategy design pattern missing the Context. Figure 1 shows the difference between a Near Strategy and true Strategy design pattern:

Figure 1: The Near Strategy design and the Strategy Design pattern

Figure 1: The Near Strategy design and the Strategy Design pattern

The HTML UI and the Client are not a part of the Strategy design pattern, but in this example, both are required for making requests. Before going on, try out the program by clicking the Play button and download all of the files.

PlayDownload

You can use the files “as-is” but you will need to change the IConnectInfo.php file so that the hostname (HOST), user name (UNAME), database name (DBNAME) and password (PW) is your actual MySql database. Also, once you create a table with a name of your choosing, be careful not to create it again if you want to keep your data entered into the table!

Using Form Names for Concrete Strategy Names

One of the coolest features of PHP is the ability to use strings to create instances of classes (aka: objects). For example,

$myVar = “MyClass”;
$myObject = new $myVar();

creates an instance of the class, MyClass. Knowing this, we can create the class names in HTML as form values. For instance:




The selected radio button value can be passed in a super-global to PHP:


$myVar = $_POST[‘callme’];
$myObject = new $myVar();

Using this, the Client doe not have to work through conditional statements to decide which request to fulfill. Like the Strategy design pattern, even the Client is free from using conditional statements as can be seen in the following listing:

< ?php
function __autoload($class_name) 
{
    include $class_name . '.php';
}
Class Client
{
    private $chooser;
    private $instance;
 
    public function __construct()
    {
        $this->chooser=$_POST['sql'];
        $object=$this->chooser;
        $this->instance=new $object();
    } 
}
$worker=new Client();
?>

As you can see the Client class is pretty simple with no conditional statements. It takes the value of the radio button send with a Post method. The radio button group is named “sql”; so whatever button is clicked is translated into an object.
Continue reading ‘PHP Near Strategy Design Pattern Part I: No Conditionals, Please’

Choosing a PHP Design Pattern: Part III —Intentions & Encapsulating Variation

PickDP3I was very sorry when I found out that your intentions were good and not what I supposed they were.Sitting Bull after the Battle of Little Big Horn

Easing into a Selection

We have a bumper crop of peaches this year, and I’ve been peeling, slicing and freezing peaches for the last couple of weeks. It reminded me that Part III of Choosing a PHP Design Pattern is due. This is the third and last installment in the series. You might want to take a look at Part I and/or Part II of this series before or after looking at this post.

Wouldn’t it be nice if you could type in the name of your intended project and up pops the best possible design pattern for that project? Even if you hold your breath until you turn blue, that’s not going to happen. However, such a project (a DP Picker) is a worthy one. You can begin to narrow down your choices by asking whether your project is one that belongs in the Creational, Structural or Behavioral categories. If you’re lucky, you’ll end up with the Creational category and only have five patterns from which to choose. (Since the Singleton is one of that group, you really only have to choose from four.) The following is a summary of each category. (The major sections of Learning PHP Design Patterns begin with a brief overview of each category. See pages 77, 121 and 167.)

  • Choose Creational When…You want to abstract the instantiation process and separate the use of the object from its creation.
  • Choose Structural When…You want to create larger structures from classes and objects.
  • Choose Behavioral When…You must focus of the communication between objects and the interaction between those objects.

Suppose I want to make an app that spends a lot of time loading and unloading different types of data and/or objects—which is something I often do. I’d probably want to choose a Creational pattern because I’m instantiating and removing lots of objects. Never mind which one; that’ll come later, but I’ve certainly narrowed my choices. On the other hand, if my main focus is going to be a game program, I’m going to need a good deal of inter-object communication and interaction and so I’m going to be looking at the Behavioral patterns. That will leave me with about half of the 24 patterns, but it’s a start.

Attention to Intention

The 24 different patterns have 24 different intentions (The Adapter pattern is counted twice since it has both Class and Object versions). The Gang of Four advise us to study the intention of each pattern to help make a decision about which one to use. Rather than listing them here, you can use the table developed in an earlier post, Design Pattern Variation and Intents Table, where you can also download the code for the table. Click the Play button to see the table:
Play

So what is an intention? Let’s take a look at the Proxy intention to get an idea:

Proxy Intention: Provide a surrogate or placeholder for another object to control access to it.

That kind of intention is pretty easy to envision. A login is one example where the user is logging into the Proxy and not the Real object. This was shown in Chapter 11 of Learning PHP Design Patterns and in a post on the Proxy pattern on this blog. (Click below to continue.)
Continue reading ‘Choosing a PHP Design Pattern: Part III —Intentions & Encapsulating Variation’

Choosing a PHP Design Pattern: Part II—Avoiding Redesign

PickDP2What are the causes of System Redesign?

To get started on Part 2 of choosing a design pattern, we need to look at the causes of redesign. I realize that his is jumping ahead in the list, but because the issue of re-design is at the heart of design patterns, it’s a good place for the second discussion of choosing a design pattern. The Gang of Four point out eight causes, and these causes each have design patterns that will help you avoid this redesign (see pp. 23-25 in GoF.) In this session, we’ll review the eight causes and the suggested patterns that can be used to avoid redesign. Look for the cause of redesign that best fits your system or general type of app.

Creating an object by Specifying a Class Explicitly

In one sense, this cause for redesign can be handled by the what you might do in making a movie deal–

Talk to my agent…

You don’t want to deal with the lawyers, contracts and all the negotiations required to make a movie deal. You just want to read the script, rehearse and get your lines straight. You let Murray (your agent) do all of that for you so you don’t get all tangled up with details you don’t know about or want to know about. Right away, you may be thinking,

That sounds like a Factory…

That’s right! You let the factory deal with the class your client wants to make a request from. A Proxy or Prototype would be another choice for separating request from the class you’re making the request to.

Dependence on specific Operations

Another cause for re-design is a dependence on specific operations which may change. The reason for changing an operation or a set of operations can be anything from a bright idea you get for a better way to set up the operations to changes in the objects the used by the operations. It could also be due to a new operation you want to add to the system. Suppose your system has an operation that handles the request for a phone number. The number could be anything from a land-line phone to a Skype number or something in the future none of us have even though of. You don’t want change in or the addition of a single operation to cause re-design for the whole site. So avoid hard-coded requests and let the decisions be made at compile time or run time. Two examples that avoid tightly bound requests are the Chain of Responsibility and Command patterns.

Dependence on Hardware and Software platforms

If you’re programming on a fairly low level, hardware differences can be more pronounced because you can program directly to the processor. PHP is a server-side language sent to a browser and it doesn’t matter is the user’s system is Linux, Windows and Mac operating systems. So platform is not something we tend to worry about or even have to concern ourselves with—albeit a few exceptions.

Having written design patterns for PHP5+, ActionScript 3.0 and a little Java, I am able to preserve most structures in a cross-language environment. However, I do need to attend to language differences, such as the fact that PHP5+ is weakly typed and ActionScript 3.0 is strongly typed. Gamma and associates suggest the Abstract Factory and Bridge designs to help overcome any software dependencies that may arise. The high level abstraction in both patterns helps to ameliorate any differences in hardware and software. However, most design patterns encourage communication between interfaces rather than concrete implementations, and so I would suggest that most (if not all) design patterns have a healthy regard for cross-platform and cross-API cases.

Dependence on Object Representations or Implementations

<em><strong>Figure 1:</strong>Works like Bait & Switch—as long as the interface is the same, it can make the request</em>

Figure 1: Works like Bait & Switch—as long as the interface is the same, it can make the request

We assume when we build a client class that it will simply make requests. However, to make those requests it has to know how an object is represented, stored, located, and implemented. Rather than having that responsibility thrust upon the client, GoF suggest hiding that information from the client. Then if changes are made, the client can make the same request and the information will be handled through abstract structures where change will not ripple through to the client nor the program. Figure 1 suggests that the Client doesn’t know what it’s getting itself into, and in this case, that’s a good thing! The Abstract Factory and Bridge designs along with Memento and Proxy designs keep request processing information hidden from the client, and so when changes are made, the client can make the same requests but get different implementations representing any changes to the system.
Continue reading ‘Choosing a PHP Design Pattern: Part II—Avoiding Redesign’

Choosing a PHP Design Pattern: Part I—Selection Criteria

PickDP Which Design Pattern?

One of the most persistent questions that I get is, How do you select a Design Pattern?, and usually, my response is, Decide what varies and see which pattern handles that variation. Of course, you will find that lots of things vary, and deciding which one to build a design pattern around can be tricky. Furthermore, GoF have lots more to say about how to go about choosing a design pattern than just encapsulating variation. This series will cover the different criteria so that we can get a complete picture of the selection process.

Gamma, Helm, Johnson and Vlissides (aka Gang of Four) provide six criteria for making a selection (pp.28-30). They include:

  • Consider how design patterns solve design problems
  • Scan Intent sections
  • Study how patterns interrelate
  • Study patterns of like purpose
  • Examine a cause of redesign
  • Consider what should be variable in your design

Many of the selection solutions that GoF offer are simply references to a part of their book that discusses what design patterns do (which you may not have yet read), and so I’m going to try and summarize each of these criteria. That may result in an oversimplification, and you’re welcome to point out any such misstep I make and set me straight if you believe that a summarized explanation is too terse. (Better yet, go over pp. 11-31 and read all of the detail yourself.)

Consider how design patterns solve design problems

Section 1.6 (pp. 11-28) of Design Patterns is laden with major concepts and information about design pattern use as a strategy for solving design problems in programming. The foundation in finding an appropriate object is the idea that,

objects package both data and procedures that operate on data, and the only way that an object performs an operation is when it receives a request from a client.

Implied in that idea is that an objects’s internal states are encapsulated. You know what that is, and so we can move on to the central OOP issue of decomposing a system into objects. How do you do that? It’s not easy because you have so many factors to consider (some of which may be conflicting) in the decomposition process.

Figure 1: Breaking down complexity into simple parts

Figure 1: Breaking down complexity into simple parts

So what is the decomposition process? Basically, it’s breaking down a complex problem down into smaller, more manageable units—in the case of PHP design patterns, classes, (objects). At the root of all English literature is the alphabet. (See Figure 1) The degree to which you decompose a task refers to its granularity. Breaking down the works of Shakespeare can have different levels of granularity. For example all of Shakespeare’s works can be broken down into plays, plays into acts, acts into scenes, scenes into paragraphs, paragraphs into sentences, sentences into words, and finally words into letters of the alphabet. The degree of granularity depends on what you need. Understanding the alphabet will not help you understand much about Shakespeare, but if you don’t know the alphabet, you cannot read his plays, sonnets and poems. (See Object Granularity below).

Beginning with the problem (e.g., How to make a sniffer, how to create a UI for an online store, how securely store and retrieve data), you have to decide the way in which you want to break it down. (It’s not going to break itself down!) The only thing that has ever worked for me is knowing exactly what I want to do. In other words, you need some serious understanding of the problem itself. So even before you begin to work through the decomposition process, you need to study the project you want to complete. The OOP process for decomposition has different approaches:

  • Write a problem statement and create classes and operations from nouns and verbs in the statement.
  • Focus on the collaborations and responsibilities in the system (problem you’re trying to solve).
  • Model the real world and translate the objects found during analysis into design.

At one time or another, I’ve used all of these approaches, and they all work. Usually, I find myself going between them, combining them—shaking the box with the problem inside to see how things settle at the bottom. However, it’s difficult to provide a generic case, and so I’ll provide two cases that I actually worked through.
Continue reading ‘Choosing a PHP Design Pattern: Part I—Selection Criteria’