Applying design patterns to web development

Part 1: The strategy pattern

One of my biggest efforts as a developer is to apply design patterns to my software designs and implementations. When I’m working with PHP is where I most feel the lack of OO approaches in many cases. PHP started as a procedural language, with a few functions serving for a limited amount of tasks, but like anything in this world, it has evolved into a more mature language. The problem is that many tutorials around the web are meant for starting as a developer and tend to leave Object Orientation out of the box, which is a trend that I find awful.

Sadly, there are still many PHP developers writing procedural code and calling it object oriented because they use the word class. Writing OO code is a bit more complex than that, we need to “think” how to express our problem into objects and how to make them communicate, not to create monolithic systems with strongly coupled components, which turns into software impossible to maintain, document, test and most importantly reuse and scale.

Well, back to the main idea, in this blog post I intend to use the strategy design pattern, which is one of the most implemented design patterns when it comes to web systems. The definition of the strategy pattern is:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

The classic scenario is a situation where we can employ different variants depending on the environment. For instance, Session Management is an important task on every web application. If we are going to create a small application, then using the standard PHP session implementation, we are good to go. But this does pose two main problems:

  1. If we are in a shared hosting, anybody in the same server can work around the server´s security and copy the session files thus gaining access to data we don’t want them to have.
  2. If we want to scale our application, like adding extra servers, moving the application to a cluster or something like it, sharing the session files is a nightmare for managing the sessions

So, we have two main scenarios, where we are able to use the standard session driver and where we have to use a more advanced session management system, like for instance a database approach or integrating with Memcached or another powerful solution.

The initial approach is to write a PHP file called sessions.php and there do something like this:

$driver = $configuration[“session”]->getFile();
include $driver . “.php”;

And driver would be a file performing the calls to the session_set_save_handler function which changes the functions for managing the sessions, and of course, the implementation of such functions.

An approach like that one does the job, but we would have no objects, just a bunch of files. The real Object oriented version would be defining the contract of how we want to interact with the drivers. In our case, we have a session driver, which could hold a few operations, basing on the session_set_save_handler function arguments, we would need 6 methods in our interface: Open, Close, Read, Write, Destroy and GarbageCollect.We would have something like this:

interface ISessionDriver
{
   public function Open();
   public function Close();
   public function Read();
   public function Write();
   public function Destroy();
   public  function GarbageCollect();
}

Now, we have an interface, and we can register the interface as the session provider. To do that we have again two methods, the first one is loading from the configuration the class we want to load, and we’ll see the second soon on how to use Dependency Injection.

The idea is very much like the first functional approach, include the template file, but now we know that we’ll have a class implementing the ISessionDriver interface, a class which respects a contract previously established by me. Again, we would do a code quite similar, but now we would check:

$driver = $configuration[“session”]->getFile();
   include $driver . “.php”;
   $driverInstance = new $driver();

   if ($driverInstance instanceof ISessionDriver){
      //register the session driver
   }
   else
      throw new SystemException(“Expecting an ISessionDriver here!”);

With that we finish the first part of how to decouple our classes into a more reusable environment, applying the strategy design pattern and we will get deeper into it soon by using dependency injection to make this design even more decoupled.

4 comments:

  1. This is a really good read for me. Must agree that you are one of the coolest bloggers I ever saw. Thanks for posting this informative article.

    ReplyDelete
  2. Thanks a lot! Hope you enjoy future posts as well...

    ReplyDelete
  3. really good blog ..nice strategy..

    ReplyDelete
  4. Very nice post here and thanks for it .I always like and such a super contents of these post.Excellent and very cool idea and great content of different kinds of the valuable information's.
    Web Development Company in India

    ReplyDelete

Commenting is allowed!