Sample of PHP: Design Patterns Adapter

About the Adapter

In the Adapter Design Pattern, a class converts the interface of one class to be what another class expects.

In this example we have a SimpleBook class that has a getAuthor() and getTitle() methods. The client, testAdapter.php, expects a getAuthorAndTitle() method. To “adapt” SimpleBook for testAdapter we have an adapter class, BookAdapter, which takes in an instance of SimpleBook, and uses the SimpleBook getAuthor() and getTitle() methods in it’s own getAuthorAndTitle() method.

Adapters are helpful if you want to use a class that doesn’t have quite the exact methods you need, and you can’t change the orignal class. The adapter can take the methods you can access in the original class, and adapt them into the methods you need.

SimpleBook.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

  class SimpleBook {

    private $author;
    private $title;

    function __construct($author_in, $title_in) {
      $this->author = $author_in;
      $this->title  = $title_in;
    }

    function getAuthor() {return $this->author;}

    function getTitle() {return $this->title;}

  }
download source, use right-click and “Save Target As…” to save with a .php extension.

BookAdapter.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

  include_once('SimpleBook.php');

  class BookAdapter {

    private $book;

    function __construct(SimpleBook $book_in) {
      $this->book = $book_in;
    }

    function getAuthorAndTitle() {
      return $this->book->getTitle() . ' by ' . $this->book->getAuthor();
    }

  }
download source, use right-click and “Save Target As…” to save with a .php extension.

testAdapter.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

  include_once('SimpleBook.php');
  include_once('BookAdapter.php');

  define('BR', '<'.'BR'.'>');

  echo 'BEGIN TESTING ADAPTER PATTERN'.BR;
  echo BR;

  $book = new SimpleBook("Gamma, Helm, Johnson, and Vlissides",
                         "Design Patterns");

  $bookAdapter = new BookAdapter($book);

  echo 'Author and Title: '.$bookAdapter->getAuthorAndTitle();

  echo BR.BR;
  echo 'END TESTING ADAPTER PATTERN'.BR;
download source, use right-click and “Save Target As…” to save with a .php extension.

output of testAdapter.php

BEGIN TESTING ADAPTER PATTERN

Author and Title: Design Patterns by Gamma, Helm, Johnson, and Vlissides

END TESTING ADAPTER PATTERN

Sample of PHP: Design Patterns Facade

About the Facade

In the facade pattern a class hides a complex subsystem from a calling class. In turn, the complex subsystem will know nothing of the calling class.

In this example, the CaseReverseFacade class will call a subsystem to reverse the case of a string passed from the Book class. The subsystem is controlled by the reverseCase function in the CaseReverseFacade, which in turn calls functions in the ArrayCaseReverse and ArrayStringFunctions classes. As written, the CaseReverseFacade can reverse the case of any string, but it could easily be changed to only reverse a single element of a single class.

In my example I make all elements of the Facade and the subsystem static. This could also easily be changed.

Book.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved
  class Book {
    private $author;
    private $title;
    function __construct($title_in, $author_in) {
      $this->author = $author_in;
      $this->title  = $title_in;
    }
    function getAuthor() {return $this->author;}
    function getTitle() {return $this->title;}
    function getAuthorAndTitle() {
      return $this->getTitle() . ' by ' . $this->getAuthor();
    }
  }
download source, use right-click and “Save Target As…” to save with a .php extension.

CaseReverseFacade.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved
  class CaseReverseFacade {
    public static function reverseStringCase($stringIn) {
      $arrayFromString = 
	    ArrayStringFunctions::stringToArray($stringIn);
      $reversedCaseArray = 
	    ArrayCaseReverse::reverseCase($arrayFromString);
      $reversedCaseString = 
	    ArrayStringFunctions::arrayToString($reversedCaseArray);
	  return $reversedCaseString;
    }
  }
download source, use right-click and “Save Target As…” to save with a .php extension.

ArrayCaseReverse.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved
  class ArrayCaseReverse {
	private static $uppercase_array = 
	  array('A', 'B', 'C', 'D', 'E', 'F',
	        'G', 'H', 'I', 'J', 'K', 'L',
	        'M', 'N', 'O', 'P', 'Q', 'R',
	        'S', 'T', 'U', 'V', 'W', 'X',
	        'Y', 'Z');
	private static $lowercase_array = 
	  array('a', 'b', 'c', 'd', 'e', 'f',
	        'g', 'h', 'i', 'j', 'k', 'l',
	        'm', 'n', 'o', 'p', 'q', 'r',
	        's', 't', 'u', 'v', 'w', 'x',
	        'y', 'z');
    public static function reverseCase($arrayIn) {
      $array_out = array();

	  for ($x = 0; $x < count($arrayIn); $x++) {
	    if (in_array($arrayIn[$x], self::$uppercase_array)) {
          $key = array_search($arrayIn[$x], self::$uppercase_array);
		  $array_out[$x] = self::$lowercase_array[$key];
	    } elseif (in_array($arrayIn[$x], self::$lowercase_array)) {
          $key = array_search($arrayIn[$x], self::$lowercase_array);
		  $array_out[$x] = self::$uppercase_array[$key];
		} else {
		  $array_out[$x] = $arrayIn[$x];
		}
	  }
	  return $array_out;
    }
  }
download source, use right-click and “Save Target As…” to save with a .php extension.

ArrayStringFunctions.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved
  class ArrayStringFunctions {
    public static function arrayToString($arrayIn) {
      $string_out = NULL;
	  foreach ($arrayIn as $oneChar) {
	    $string_out .= $oneChar;
	  }
	  return $string_out;
    }
    public static function stringToArray($stringIn) {
      return str_split($stringIn);
    }
  }
download source, use right-click and “Save Target As…” to save with a .php extension.

testFacade.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved
  include_once('ArrayCaseReverse.php');  
  include_once('ArrayStringFunctions.php');
  include_once('Book.php');  
  include_once('CaseReverseFacade.php');
  echo tagins("html");
  echo tagins("head");  
  echo tagins("/head");  
  echo tagins("body");
  echo "BEGIN TESTING FACADE PATTERN";
  echo tagins("br").tagins("br");

  $book = 
    new Book("Design Patterns",
	            "Gamma, Helm, Johnson, and Vlissides");
  echo "Original book title: ".$book->getTitle();
  echo tagins("br").tagins("br");
  $bookTitleReversed = 
    CaseReverseFacade::reverseStringCase($book->getTitle());  

  echo "Reversed book title: ".$bookTitleReversed;
  echo tagins("br").tagins("br");
  echo "END TESTING FACADE PATTERN";
  echo tagins("br");
  echo tagins("/body");
  echo tagins("/html");
  //doing this so code can be displayed without breaks
  function tagins($stuffing) {
    return "<".$stuffing.">";
  }
download source, use right-click and “Save Target As…” to save with a .php extension.

output of testFacade.php

BEGIN TESTING FACADE PATTERN
Original book title: Design Patterns
Reversed book title: dESIGNpATTERNS
END TESTING FACADE PATTERN

Design Pattern: Adapter vs Facade

During my recent round of interviews for my next consulting gig I was exposed to a barrage of “off the shelf” technical interview questions. Fortunately for you I am not going to bore you with them in this post (though I may choose to regale you with these tales at a later time). A fair number of the questions that I was asked glanced off of and dodged around the topic of design patterns. In one such interview the Adapter Pattern came to the forefront of the conversation. I say “conversation” because I prefer to conduct and participate in interviews using a conversational style rather than the oft used interrogation style, a series of rapid fire questions given as the interviewer checks off the answers on his answer sheet. As I completed my eloquent explanation of the pattern one interviewer asked me, “What is the difference between the Adapter and the Facade pattern? They seem like they are doing the same thing to me.”

This question really caught me off guard because until that moment I had not given it much thought. In my mind they are distinct patterns that solve different problems. It is never good in an interview to appear that you have been caught off guard so I mustered a meek answer. After further thought and consideration I have developed a much stronger response to the interviewer’s question.

In this post I will clearly demonstrate the differences between these two patterns by crystallizing their intent and demonstrating when it would be appropriate to use each pattern.

Scenario 1: The Adapter Pattern 
Assume that we are faced with the following situation. We have an existing class in our system called “A”. We have decided that we need to change the “B” class to use the “A” class rather than the “C” class it is currently using. However, “B” is dependent on the “C” interface which is different from the one exposed by “A”. How do we make this work?

The Adapter Pattern is intended to help us solve just this problem by creating a class that “adapts” the exposed interface of a class to an interface that is expected by the new client. To use this pattern to solve the problem described earlier we create a third class called “A2C” that has the “C” interface that the “B” class is expecting. Inside our “A2C” class is the necessary logic to wire the “B” class to the “A” class without either of the existing classes having to change in any material way. Now we just change “B” to depend on “A2C” rather than depending on “C”. If we were smart enough to inject this dependency into “B” then “B” won’t have to change at all. This keeps us from having to change “A” and in doing so makes it impossible for us to break “A” and any of its other clients.


Scenario 2: The Facade Pattern 
For scenario 2 assume that we are dealing with the following circumstances. We need to integrate our new application with an existing legacy subsystem. This subsystem has a relatively complex API that consists of a number of class each with a number of public methods. To integrate our new application with this subsystem we need to instantiate only some of the classes and then use these objects via a few of the methods calls on each object. How should we integrate with this subsystem?

Keep in mind that we are integrating with a subsystem here. So it’s possible that one day this entire subsystem could be replaced. If we integrate directly with each class and method directly then we have created a tight coupling between our new application and the subsystem and if the underlying subsystem did change then we would have to go into our new application and do some “shotgun surgery” to fix all of our dependencies. A better solution is to create an abstraction layer that would insulate us from future changes in the subsystem and simplify the API, all at the same time? The Facade Pattern has the recipe to help us create this abstraction layer. I can always remember the Facade Pattern because I think of Facade in the construction/building/architecture sense. In these terms, a Facade is a thin decorative front that is used to hide something ugly underneath it. The Facade design pattern has a similar definition, in that it is used to make an complex API simpler and (hopefully) prettier to the client.

So we have decided to implement the Facade pattern. We do this by creating our Facade class. This class exposes a minimal set of public methods that our new system will use in lieu of communicating directly with the subsystem. The Facade class will handle the object creation for any classes in the subsystem that are needed. Now if the underlying subsystem ever changes or is replaced the impact to our new system will be limited to the Facade class that we have created.

What We Have Learned 
The Adapter Pattern and the Facade Pattern solve different problems. As we have seen each pattern has a different intent and a different implementation. The intent of the Adapter Pattern is to adapt one classes interface into an expected interface used by an existing client class or classes. The intent of the Facade Pattern is to simplify the API of a subsystem.

So to answer that interviewer’s question again, “No! These patterns are not doing the same thing. They are intended to do very different things and solve very different problems.”