Archive for the 'Factory Method' Category

Page 2 of 2

PHP Skip Lists 2: Implementing Skip Lists in PHP

GunMoll250The Perfect Skip List

I ran across the perfect skip list in a presentation by Eileen Kraemer, a computer science professor at the University of Georgia. (You can find several academic papers on the perfect skip list if you do a Web search: key = perfect skip list.) In the most simple terms, the perfect skip list is one where each level has exactly double the nodes as the one above it. In a sense, it is arranged like a binary search. The head node (far left) has a value of minus infinity using the PHP constant with a minus sign (-INF) and the node on the far right has a value of infinity, (INF). (I’m calling the far right node the tail node for the sake of symmetry. You’ll also see it labeled the “sentinel.”) By having the highest and lowest possible values bracketing the search values, it contains the search parameters so that you can enter any values you want in the skip list. Figure 1 shows the perfect skip list without values except for the tail node with a value of infinity.

Figure 1: Perfect Skip List

Figure 1: Perfect Skip List


That looks a lot like the train lines used in the previous post on skip lists, and if it helps to visualize the skip list as train lines to see what’s going on, you can think of them as such. Figure 1 also may remind you of a binary search pattern, and that’s because perfect skip lists and binary searches have a lot in common. All that’s left to do is to program it. First, though, give it a quick play and download the files:
PlayDownload

Programming Skip Lists with the SplDoublyLinkedList class

Most of what you need to know about programming linked lists can be found in the post on Linked Lists on this blog. Using the built-in PHP SplDoublyLinkedList class (PHP 5.3+), I generated five linked lists, naming them level4 to level0, reflecting those in Figure 1. The trick was in figuring out how to best iterate through the lists. Here’s the iteration process I was looking for:

  • Start with level4 and check the first node to the right
  • If less than move down one level; greater than move right
  • Synch list nodes with levels
  • Repeat until match found

Initially, I tried using the next() and prev() methods in the SplDoublyLinkedList class, but it was very difficult to synch all levels with those methods. Then I tried using the offsetGet(n) method, and it worked easily and well for both searching and synching levels.

The Skip List Product and Factory

A Factory Method design pattern serves to create the linked lists and final skip list. Figure 2 shows the class diagram in file format:

Figure 2: File Diagram of Skip List Factory Method pattern

Figure 2: File Diagram of Skip List Factory Method pattern

The Client makes all requests through the factory for linked lists. The lists themselves have been configured as implemented products, and the Client puts them together as a skip list. An alternative design would have been to have a fully loaded SkipList class (an encapsulated skip list) and have the Client pass on search requests with the search methods in the SkipList class instead of the Client. Either way, the Factory Method has ensured loose binding, and so if you’d like to experiment with a separate skip list class, go ahead. (Click below to see how the different objects are implemented.)
Continue reading ‘PHP Skip Lists 2: Implementing Skip Lists in PHP’

Share

PHP CMS Project Part V: The Factory Method

cms5A Simple Factory Method CMS

In deciding which design pattern to apply to this CMS, two came to mind. Because PHP is creating a Web page, creational patterns appeared to be the most appropriate. Both the Factory Method and the Abstract Factory were considered. The Factory Method is the simplest of the two and it can be expanded, and so I settled on it. The Abstract Factory would be more appropriate if the main goal was to select different Web page styles. This CMS is to update and use data from a MySQL table. Since a lot of files make up this CMS, it’s probably a good idea to download them first:
Download

To get started, take a look at Figure 1. In Part IV of this series you saw how to put data into and retrieve it from a database and use in a Web page. That is pretty much what has been done here except the request is through the Creator interface to insure loose coupling. The PageCreator implements the factoryMethod() method which creates a requested product specified by the Client. As a result the Client is only loosely bound to the concrete product it requests.

Figure 1: File Diagram for Factory Method CMS

Figure 1: File Diagram for Factory Method CMS

When the concrete creator object (PageCreator) passes the request for the concrete Product object (PageProduct1()), it does so through the deliverWeb() method—the method implemented through the Product interface.

Multiple Inheritance (Sort of)

Some languages like Java and Python support multiple inheritance. Strictly speaking, PHP does not, but you will find workarounds and you can combine inheritance and implementation in a single child class. In the declaration of the PageProduct1 class, you can see how this is done:

<?php
include_once('UniversalConnect.php');
include_once('Product.php');
include_once('ProductTools.php');
class PageProduct1 extends ProductTools implements Product
{
    function deliverWeb()
    {      
        $this->tableMaster="blogette";
        $this->hookup=UniversalConnect::doConnect();
        $this->loadContent();
        $this->content = array("css" => $this->css,
                         "title" => $this->title,
                         "header1" => $this->header1,
                         "header2" => $this->header2,
                         "body1" => $this->body1,
                         "body2" => $this->body2,
                         "image1" => $this->image1,
                         "image2" => $this->image2,
                         "caption1" => $this->caption1,
                         "caption2" => $this->caption2
                         );   
        return $this->content;
    }
 
    private function loadContent()
    {
        //Create Query Statement
	$this->sql ="SELECT * FROM $this->tableMaster WHERE id = 1";
 
	if ($result = $this->hookup->query($this->sql))
	{
	    while ($row = $result->fetch_assoc()) 
	    {
                $this->css = $row['css'];
                $this->title = $row['title'];
                $this->header1 = $row['header1'];
                $this->header2 = $row['header2'];
                $this->body1 = $row['body1'] . "<p />";
                $this->body2 = $row['body2'] . "<p />";
                $this->image1 = "images/" . $row['image1'];
                $this->image2 = "images/" . $row['image2'];
                $this->caption1 = $row['caption1'];
                $this->caption2 = $row['caption2'];
	    }
            $result->close();
	}
        $this->hookup->close(); 
    }
}
?>

The declaration line:

class PageProduct1 extends ProductTools implements Product

imbues PageProduct1 with both the properties of the ProductTools and the interface of the Product. By having the abstract class ProductTools provide the essential properties of a Product child, the properties need not be declared in the concrete product child classes and add some uniformity. At the same time the Product child implementations have the common Product interface. If you’re thinking that a single abstract class could have handled both the method and the properties, you’d be right. However, but having a separate class for properties, the same design could easily be adapted to include a whole new set of properties if need be.

You probably recognize PageProduct1 as the RetrieveBlog class from Part IV of the CMS series. About the only difference is that I created an abstract class ProductTools to store common product properties for use by any other product classes that the developer may care to add. It reduces clutter and makes it easier to make small changes. For example, one strategy considered is to create several different instances of PageProduct1, such as PageProduct2, PageProduct3 and so on. Each could simply identify a different table ID number to be called from the Client class. On the other hand, new data could be added simply by using an UPDATE SQL command to change the content of the record with an ID selected by the class.

Figure 2 shows an added page delivered as a concrete product upon a Client request, and as you can see, it looks just like the others in this series, but the content has changed:

Figure 2: Page created with Factory Method CMS

Figure 2: Page created with Factory Method CMS

The nature of the page has not changed, but the way in which it is requested has. The request is through the Creator interface; so next we’ll take a look at the concrete creator class and the new Client class.

Request to the Creator

The real “un-coupler” participant in the Factory Method design pattern is the Creator and its implementations. In this instance, the single concrete class passes on the request from the Client for a Product. In the following listing are both the Creator abstract class and its child class, PageCreator: (Note: Product type hinting is used so that additional concrete product implementations may be called through the same interface. This is an example of the design pattern principle of program to the interface (Product) and not the implementation (PageProduct1).

<?php
//Creator.php
abstract class Creator
{
	protected $webProduct;
	abstract public function factoryMethod(Product $pageNow);
}
?>
 
?php
//ConcreteCreator.php
include_once('Creator.php');
 
class PageCreator extends Creator
{
	public function factoryMethod(Product $pageNow)
	{
		$this->webProduct=new $pageNow();
		return($this->webProduct->deliverWeb());
	}
}
?>

At this point, you may wonder where the content of the $pageNow parameter comes from. In this case, and all along in this series actually, the Web page has been the client. It is requesting content for the HEREDOC page. So, we might as well put it where it belongs—in the Client class as shown:

<?php
include_once('PageProduct1.php');
include_once('PageCreator.php');
 
class Client
{
    private $content;
    private $document;
    private $hd;
 
    function __construct()
    {
        $this->content=new PageCreator();
        $this->hd = $this->content->factoryMethod(new PageProduct1());
        $this->document = <<<CMSTEMPLATE
        <!DOCTYPE html>
        <html>
        <head>
        <link rel="stylesheet" type="text/css" href={$this->hd["css"]}>
        <meta charset="UTF-8">
        <title>{$this->hd["title"]}</title>
        </head>
        <body>
        <header>
            <h1>{$this->hd["header1"]}</h1>
        </header>
            <article>
                <header>
                <h2>{$this->hd["header2"]}</h2>
                </header>
                {$this->hd["body1"]}
                {$this->hd["body2"]}
                <section class="doRight" >
                    <img src={$this->hd["image1"]}>
                    <caption ><span class="pixcaption"><br />{$this->hd["caption1"]}</span> </caption>
                </section>
                <section class="doLeft">
                    <img src={$this->hd["image2"]}>
                    <caption><span class="pixcaption"><br />{$this->hd["caption2"]}</span> </caption>
                </section>
            </article>
        </body>
        </html>
 
CMSTEMPLATE;
    echo $this->document;
    }
}
$worker = new Client();
?>

The two lines in the Client that show it to be part of a Factory Method design pattern are:

$this->content=new PageCreator();
$this->hd = $this->content->factoryMethod(new PageProduct1());

The Client makes the request through the PageCreator class and then invokes the factoryMethod() to specify the product, PageProduct1. Now suppose later that you want to make more products—implementations of the Product interface. Because the request in the Creator specifies through type hinting is for the Product and not any specific implementation of the Product interface, it can handle any Product implementation.

You may want to review other implementations of the Factory Method on this blog for a review in understanding how everything works together. However, it comes down to Request -> Creator -> Product.

The CMS Co-Stars

In wrapping up this series on creating a CMS using a design pattern in PHP, you will find a folder full of some of the tools you’ll need for creating and maintaining the system in a folder named “Administrative.” At some point soon, I hope to implement it for the http://www.sandlight.com site, and I’d be very interested in what others have done or ideas for making it better. In the meantime enjoy exploring its possibilities.

Share

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’

Share

PHP Factory Method Design Pattern : Decoupling Your Products

Let the Factory Build Your Products

One of the easiest design patterns to both understand and create is the Factory Method. However, the Gang of Four provide more than a single basic structure for the pattern and do not specify exactly where the Client makes its request. As a result, one may not recognize one implementation or another. Generally, I assume that requests from the Client class are made directly through the Creator class. However, some implementations suggest that the Client holds a reference to both the Creator and Product (GoF, 110). For this example I chose to use a parameterized version. In this version of the Factory Method pattern, the factory method is allowed to create multiple kinds of products. As noted by GoF,

The factory method takes a parameter that identifies the kind of object to create. All objects the factory method creates will share the Product interface.(pp. 110-111).

This approach calls for an abstract class that can handle a wide variety of concrete products. At the same time, though, we want it to be useful as well. For this example, the Product class has an abstract method to generate the concrete product (getData), but it also holds the properties with the connection values for the MySQL server. So this allows the developer to change the contents of the concrete products without having to even think about the connection values. (This assumes that the same connection information is used by all of the products.) Figure 1 shows the class diagram for this kind of Factory Method implementation.

Figure 1: Parameterized Factory Method Class Diagram

The Client’s role is implied to hold references to the Creator class (factory) and the Product class. The Product reference is through a parameter in the Creator instance. Because the the Creator interface holds a Product as its parameter in the form of a type hint, the request from the Client is to the abstract Product class and not the concrete product declared in the ConcreteCreator parameter. As a result, it’s easy to add more concrete products without having to re-write the whole program. You can just add the new concrete product class with the appropriate interfaces and call them with the Client referencing the concrete product as a parameter of the ConcreteCreator instance. For instance, the following lines shows such a request:

$this->graphicGetter=new ConcreteCreator();
print($this->graphicGetter->factoryMethod(new GraphicProduct()));

The same instance could be called again for a TextProduct. Therein lies the beauty of programming to the interface instead of the implementation. You can test the program and download the files by clicking the buttons below.

Note: When you look at the code in the downloaded files or in the listings, I used the MySQL settings from my localhost on my computer. Obviously, you will want to substitute those settings for your own; so be sure to get your own MySQL user, password, databases and tables set up before trying to run the files. Also, the project stemmed from a Dreamweaver PHP group whose names were substituted by known and unknown blues, boogie and jazz artists. Make changes in those elements to suit your tastes.

To better understand the actual program, click below to go to the steps in building the application:

Continue reading ‘PHP Factory Method Design Pattern : Decoupling Your Products’

Share