Monthly Archive for January, 2013

A Simple PHP Design Pattern: The Factory Method

Factory250mThe Easiest Design Pattern in the Galaxy

As part of a Boston PHP group’s PHP Percolate, we’re going through Larry Ullman’s PHP Advanced and Object-Oriented Programming (3ed) book. In his chapter on Design Patterns, Larry has a pattern he calls, The Factory Pattern. This pattern can be found in many PHP works, and the first mention of the pattern that I found was in a series of PHP design patterns in an IBM Website in 2006. The Factory pattern was given an “honorable mention” as a pattern in the Freemans’ incredible work, Head First Design Patterns (p 117), but the Freemans note that the Factory pattern is more of a programming idiom than a true design pattern. The design pattern found in the Gang of Four’s work is a Factory Method pattern that is a true design pattern.

In looking at the Factory Method pattern, you can see two key participants—the Creator and the Product. The requesting object (Client), goes through the Creator to request a product. The key element in the Creator is an abstract method, factoryMethod(). Figure 1 shows a bare bones class diagram of the Factory Method:

Figure 1: Factory Method Class Diagram

Figure 1: Factory Method Class Diagram

The Client makes a request using the desired product as an argument in the factoryMethod(). So, instead of asking for “product X,” its requests states, “Make me product X”—or “Factory, build product X for me.” This arrangement separates the requesting object (Client) from the requested product. Thus, it is a loose binding, and if changes are made in the product, the program does not crash and burn. That’s because the request is through the factory (Creator).

In the Factory pattern, the simple factory is often declared statically (as is the case in Larry Ullman’s book), but in the Factory Method pattern, the factoryMethod() method is declared as an abstract one that can be overridden. The reason for that is flexibility. In Figure 1, you can see that a single concrete creator is instantiating a single concrete product. However, you can have several different concrete factories requiring different implementations of the factoryMethod(). In Chapter 5 of Learning PHP Design Patterns, one of the examples has two factories (concrete creators); one for graphics and another for text captions.

The Shape Factory

This example has one product, graphic shapes. It includes a red triangle, a green square, and a blue circle—-the RGB trio. The client requests each shape by specifying the name of the product in a request through the Creator. Figure 2 shows the class diagram for this implementation.

Figure 2: Class diagram for the Shape Factory

Figure 2: Class diagram for the Shape Factory


This example only includes shapes. However, suppose instead of general shapes, you had images with captions. Instead of starting all over again, you could just add another set of implemented Products for captions and had another concrete factory (concrete creator) for text. What’s important, you’re not wasting a lot of time re-doing what you’ve already done. The bigger the program, the more this kind of structure is appreciated.

To get started, run the program and download the files using the buttons below:
PlayDownload

Once you download the source code (not to mention the incredibly valuable graphics), you’re all set to understand just what’s going on.

Factory First

In working with design patterns, it helps to think in terms of what the client wants. (The client is perhaps the most important and most overlooked participant in design patterns.) So if you start with what the client wants, the next step is to ask, “How does the client get what it wants?”

  1. Client wants a product.
  2. The client must must request the product through the factory method

Now that’s fairly simple. The client is separated from the product it is requesting, and changes to the product will not affect the process used for making the request. Likewise, changes in the client request will not affect the nature of the requested product.
Continue reading ‘A Simple PHP Design Pattern: The Factory Method’

Design Pattern Variation and Intents Table

Pie500 On several different occasions I have meant to create an easy look-up table for quickly finding all of the GoF design patterns, their general purpose, their scope, what can vary and their intent. I finally did it! Click Play to view and Download to get it for your desktop.(It’s just an HTML table; so don’t get too excited.)
PlayDownload

The next time you’re wondering what pattern to use, just give it a click and the table will faithfully appear before you.

No Time For OOP or Design Patterns

noTimeI’m Busy

A few years ago I was in New York City visiting one of the many world class advertising agencies in town. This particular agency was an award-winning media company handling the online advertising of some of the best-known brands in the world. I’d been invited to meet some people and had hoped to set up an internship for our students. At the time I had recently published a book on OOP and Design Patterns and the lead developer with whom we met, knew of my work.

I was interested in their process. Online advertising campaigns are updated on an ongoing basis, and if it’s not new and fresh, potential customers are likely to click or tap to a different site. They explained how they used a template, and most of what a lot of “developers” did was nothing more than data entry. (Not quite as glamorous as imagined.) As I asked about their process and software development work, the lead developer suddenly said,

We don’t do it correctly.

At the time I had no idea what he was talking about and let it drop. Next, he said, “Most of the time we can’t reuse the same code.” Then it dawned on me. Design patterns are known for reusable code and object oriented programming (OOP) is all about application maintenance and capacity for change. What he was saying was that they hacked through the code to get the job done. Using a template, they could cobble together a workable solution to get the project out the door on time. This is not to say they created junk as far as the end results were concerned. The software worked as expected and looked great—thanks mainly to graphic designers and world-class digital photography. They were right about one thing; hacked code is very hard to re-use.

The Guilt of the Gifted Programmer

At one time or another, just about every decent programmer I know has felt a twinge of guilt either about

  1. not learning OOP and/or
  2. not using the OOP he/she knows.

As far as learning OOP is concerned, it’s not that difficult, and if most programmers had started with OOP instead of sequential programming, they would think that OOP programming is the natural way of programming. However, most of us got started writing a little bit of code in a sequence, then we learned procedures (functions) and then procedural programming. Then by learning more coding statements, functions, operations and the like, we got better at it and were able to do more things. Most of the PHP books on programming didn’t do much to help even though some of the authors themselves were OOP programmers.

However, we knew (we all knew!) that there is a different level of programming used by professional programmers; including PHP programmers. After all, ever since PHP 5 we’ve had classes, interfaces and a bunch of other OOP tools built into PHP.

Whether you think you can or you think you can’t, you’re right.

So what’s the hold-up? There seems to be three excuses reasons for putting off this jump of faith:

  • Too busy getting PHP projects finished to take time to learn OOP
  • Too difficult and advanced (or no self-confidence)
  • Impractical: Ok for academics but not real world development

Let’s address these reasons one at at time:
Continue reading ‘No Time For OOP or Design Patterns’

Template Method: Taming Chi Square

x2Easy Order

Eeeeek! A statistic! Relax, it’s just a Chi Square. The secret to understanding complexity is decomposition and modularity. Decomposition refers to breaking down a whole into its elements. Ironically, the term is fundamental to parallel and concurrent programming where a basic process in programming, like a loop, is further decomposed into more than a single loop, but decomposition also applies to standard OOP programming as well. Any complex process broken down involves the decomposition process. Once broken down, you can attend to the individual modules—modularity.

The Template Method design pattern is a great way to modularize a complex problem, like working through a Chi Square statistic. Chapter 9 in Learning PHP Design Patterns, explains the Template Method in detail and all about “The Hollywood Principle,” but here, I want to look at the Template Method as a “modulaizer”—making complex problems manageable. To get started take a look at Figure 1:

Figure 1: 2 x 2 table with row and column totals

Figure 1: 2 x 2 table with row and column totals

Imagine that the data in the table are based on a survey you did at a PHP group, like the Boston group. Suppose that you want to find out the members language preferences based on whether the member owns a Macintosh or a Windows PC. (Sorry Linux.) You’re interested in PHP and jQuery and you record the responses in a two dimensional array. You find that the PC users favor PHP and the Mac users are evenly split between PHP and jQuery. Getting the table results in a 2 x 2 matrix like the one in Figure 1, you’re interested in whether there’s any real significance in the differences or the whole thing is random. You decide to use a Chi Square statistic to find out. Before going further you can run the application and download the files using the buttons below:
PlayDownload

It Started with a Multi-Dimentional Array

This post came out of a Boston PHP group Percolate session for advanced PHP and OOP programming. Working through Larry Ullman’s PHP Advanced and Object-Oriented Programming, 3rd Ed book, the first chapter covered multi-dimensional arrays. After creating a two-dimensional array, I then put it into a class and started playing with it. You can see it in the following listing:

< ?php
class TwoDim
{
        private $members;
        public function __construct()
        {
        $this->members= array(
                array(os => 'Mac', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'PHP'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'PC', program => 'jQuery'),
                array(os => 'PC', program => 'PHP'),
                array(os => 'Mac', program => 'jQuery')
                );
        }
        public function getArray()
        {
                return $this->members;
        }
}
?>

I wasn’t thinking at all about the Template Method, but when I decided it’d be interesting to do a Chi Square test, I found that the Template Method was both helpful and appropriate. Breaking down the steps in a Chi Square test for a 2 x 2 table is pretty easy:

  1. Get the observed cell values (O)
  2. Get the column and row totals
  3. Determine the expected frequencies (E)
  4. Calculate the Chi Square value by adding up (O-E)2 / E
  5. Compare the Chi Square value to values in a probability table where df=1 to determine the p value

Continue reading ‘Template Method: Taming Chi Square’