Implementing Patterns within PHP
PHP 5, due for release in the coming weeks, will offer users an abundance of new and enhanced features, yet perhaps none are as appealing as the vast improvements to its object-oriented capabilities. In an earlier article, I introduced these new features, showing you how to improve class management using variable and method scopes, interfaces, abstract classes, and unified constructors and destructors. These enhancements allow you to take a far more disciplined approach to development, incorporating well-documented object-oriented design solutions into your applications, known as design patterns. This article kicks off a several part series on this topic.
In this inaugural article, I have two goals in mind. First, I'll provide a general introduction to design patterns, offering some insight into their purpose, advantages, and interesting history. Second, I'll introduce two patterns, namely the Singleton and the Factory, and offer a PHP-based implementation in the form of an applicable example. In subsequent articles, I'll build upon this material, introducing other key patterns along the way.
There's a saying that goes, "Those who forget history are doomed to repeat it." This maxim certainly applies to programming. After all, it wouldn't be a stretch to say that the majority of our efforts are devoted to repeatedly solving a core set of problems. Sure, the goals and languages change, but the underlying mechanisms of our applications do not. Despite this realization, it's commonplace to almost blindly solve these problems as they arise, often with a new solution, rarely with lessons learned. This fact has not been lost on the programming community. In an effort to eliminate an otherwise vast disparity of solutions for such repeatable problems, a well-tested set of blueprints have been defined regarding their resolution. Such blueprints are known as design patterns.
Despite design patterns' profound impact on the programming discipline, it's interesting to note that early thinking on the matter originated in the field of architecture. An architect named Christopher Alexander published numerous works in the 1970's regarding his views on the commonalities of structural features found within well-designed buildings. Two of his seminal books on the topic are "A Pattern Language" and "A Timeless Way of Building", both of which are standard reading on the subject of patterns. In these works, he derides the anarchic, "anything goes" mindset which has gripped the architectural industry over the past century, and sets forth a well-constructed argument in support of the idea that each quality building component, an arch, alcove, and doorway for example, is the result of adherence to a general set of design precepts that embody a set of rules defining its composition. This rationalization served as the catalyst for software developers to start pondering whether a similar approach could be applied to program design. However, it wasn't until the publication of yet another ground-breaking work on design patterns, aptly titled "Design Patterns: Elements of Reusable Object-Oriented Software, that the practice of pattern examination really took hold in the software community.
Published in 1995, "Design Patterns" really laid the groundwork for the widespread study of pattern studies in Computer Science, defining 23 regularly occurring patterns found in object-oriented applications. It's the brainchild of four Computer Science doctorates, namely Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. For many "Design Patterns", known almost synonomously by its nickname, the "Gang of Four" or "GoF" book, ranks among the most prolific programming books ever penned. In addition to the works of Alexander, this book is a required addition to any programmer's bookshelf.
Now that you've been apprised of the basic history and thought process behind design patterns, I'd like to make a foray into the first of several pattern groupings that we'll discuss in this series: creational patterns.
Creating flexible, extensible and portable applications is largely dependent upon how well you separate, or decouple, a system from the process involved with object composition, creation and representation. In many cases, its possible to abstract these processes by way of creational patterns, which are intended to lessen the burden of object construction and class referencing through the provision of a general framework. Below, I'll introduce two of the several creational patterns at your disposal, namely the Singleton and the Factory Method.
Sometimes a single instance of a class is all that is required to effectively manage a task. Print spoolers, application logging, and database access are all examples of tasks that work well within such parameters. In each such circumstance, creating multiple instances only results in unnecessary consumption of resources, yet managing such affairs across your entire code base can be distracting and unwieldy. Given such circumstances, rather than attempt to manage that class through external means, it makes sense to place the burden of creation and management of this single instance on the class itself. Consolidating management under this single class effectively creates a single point of access to it, relieving guesswork that would otherwise have to be introduced into the application logic. This strategy is known as the Singleton pattern.