Home arrow PHP arrow Page 2 - Design Patterns in PHP - Factory Method and Abstract Factory

Factory Method - PHP

Normally, in object oriented programming, object creation is not difficult. But what if your object needs to be created based on different conditions or other matters of context? Then you will spend hours in debugging and updating--unless you know about design patterns. David Fells explains how they work, and uses the creation of a maze to illustrate his points.

TABLE OF CONTENTS:
  1. Design Patterns in PHP - Factory Method and Abstract Factory
  2. Factory Method
  3. Abstract Factory
  4. Drawbacks of the Example
  5. Conclusion
By: David Fells
Rating: starstarstarstarstar / 79
December 20, 2004

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

The first pattern used to simplify object instantiation is the Factory Method pattern. The Factory Method pattern defines an interface for object creation but defers the actual instantiation to subclasses. Take, for example, an application that processes Electronic Funds Transfers (ETFs). There are numerous types of ETFs including virtual check, credit card, wire transfer and so on. Using a non-pattern based approach, the application code requesting an ETF object would need to know precisely what subclass of ETF is needed, and it would need to know the context in which that type of ETF is requested. We would end up with code looking something like this:

switch ($etfType) {
  case ETF_VIRTUALCHECK :
    $etf = new VirtualCheck();
  $etf->processCheck();
  break;
  case ETF_CREDITCARD :
    $etf = new CreditCard();
  $etf->chargeCard();
  break;
  case ETF_WIRETRANSFER :
    $etf = new WireTransfer();
  $etf->chargeCard();
  break;
}

Any time we want to add another ETF, we would have to manually update this switch statement anywhere it appeared. We would also have to update any other conditional code that appears. The CreditCard class hinted at above offers the same problem as the ETF itself in that each credit card type (VISA, MasterCard, AMEX) has its own validation scheme and many types have different numerical formats. We would see a similar switch statement to determine what type of credit card we were dealing with either in the CreditCard class constructor or in the switch statement above creates the CreditCard object.

By implementing the Factory Method, we code our application so it only expects a class that conforms to an interface - that is, it has certain methods and properties that can be used to submit an ETF and check whether it failed or succeeded. This promotes loose coupling in the application because you are not binding a concrete subclass to application code. The result is a great increase in flexibility and maintainability. It is easy to add new ETF subclasses and implement them because you are not hard coding the application to expect a specific subclass, just a class with a specific interface. Look at this example.

class ETF {
  var $data;
  function ETF($data) {
    $this->data = $data;
  }
  function process() {}
  function getResult() {}
}

class VirtualCheck extends ETF {}
class WireTransfer extends ETF {}

class ETFFactory {
  function createETF($data) {
      switch ($data['etfType']) {
      case ETF_VIRTUALCHECK :
        return new VirtualCheck($data);;
      case ETF_WIRETRANSFER :
        return new WireTransfer($data);
      default :
        return new ETF($data);
      }
  }
}

$data = $_POST;
$etf = ETFFactory::createETF($data);
$etf->process();

This is a crude implementation but the intent should be clear. Assume the contents of $_POST represent everything you need for the type of ETF that is happening, including a 'etfType' that says what sort of ETF you are using. This would come from the user making a selection in a form and filling out the correct information. This implementation provides numerous advantages over the first.

  1. Data validation can be left entirely to the subclasses and occur without interaction from calling code.

  2. Calling code only needs to know of one way to get an ETF object.

  3. Creation logic is encapsulated - the ETFFactory decides what concrete class to create based on the contents of $data['etfType']. Calling application code knows nothing of concrete subclasses of ETF.

  4. If special measures need to be taken, such as creating a specific type of credit card object, this can take place in one location without the calling application code being involved.

Using this approach consolidates creation logic in a single class - ETFFactory. This eliminates duplication in code when an object is created in multiple locations. With the first method, if a class name is changed or a new ETF class is added, we have to modify the ETF creation code everywhere it appears in our application. With the Factory Method implementation, this is not the case. Our calling application code knows of only ETFFactory and ETF. Subclasses of ETF provide the required specialized behaviors to process themselves in the appropriate way but the calling code needs only to use the process() method.



 
 
>>> More PHP Articles          >>> More By David Fells
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: