Five common PHP design patterns-PHP Tutorial

Source: Internet
Author: User
Summary of five common PHP design patterns. The design patterns book introduces the design patterns into the software community by ErichGamma, Richard dhelm, RalphJohnson, and JohnVlissidesDesign (commonly known as the "Gang of Four "). Description Design ModeThe book introduces Design patterns to the software community by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Design (commonly known as the "Gang of Four "). The core concept behind the design pattern is very simple. After years of software development practices, Gamma and others have discovered some patterns of fixed design. just like architects designing houses and buildings, they can develop templates for bathroom locations or kitchen structures. Use these templates or Design ModeThis means that you can design better buildings faster. The same concept applies to software.

The design pattern not only represents a useful way to develop robust software faster, but also provides a method to encapsulate large concepts in friendly terms. For example, you can write a message transmission system that provides loose coupling orObserver.

It is very difficult to use small examples to demonstrate the value of the model. This is often a little practical, because the model actually plays a role in large code libraries. This article does not show large applications, so you need to think about how to apply the sample principles in your own large applications-rather than the code demonstrated in this article. This does not mean that you should not use the mode in a small application. Many good applications are developed from small applications to large applications, so there is no reason not to base on such solid coding practices.

Now that you know the design patterns and their usefulness, let's take a look at the five common patterns of PHP V5.

Factory model

Initially inDesign ModeMany design patterns are encouraged in this book.Loose coupling. To understand this concept, we 'd better talk about the hard work of many developers engaged in large-scale systems. A problem occurs when you change a code snippet. other parts of the system, which you once thought were completely unrelated, may also cause cascading damages.

This problem lies inTightly coupled. Functions and classes in a certain part of the system depend heavily on the behavior and structure of functions and classes in other parts of the system. You need a set of modes to enable these classes to communicate with each other, but do not want to closely bind them together to avoid interlocking.

In large systems, many codes depend on a few key classes. It may be difficult to change these classes. For example, assume that you haveUserClass. You want to change it to other classes read from the database, but all code references the original class read from the file. At this time, it is very convenient to use the factory model.

Factory modelIs a type that has some methods for creating objects for you. You can use the factory class to create objects without directly usingnew. In this way, if you want to change the type of the created object, you only need to change the factory. All codes used in the factory are automatically changed.

Listing 1 shows an indication column of the factory class. The server side of the equation consists of a database and a set of PHP pages that allow you to add feedback, request feedback lists, and obtain articles related to specific feedback.


Listing 1. Factory1.php
     interface IUser
{
function getName();
}

class User implements IUser
{
public function __construct( $id ) { }

public function getName()
{
return "Jack";
}
}

class UserFactory
{
public static function Create( $id )
{
return new User( $id );
}
}

$uo = UserFactory::Create( 1 );
echo( $uo->getName()."\n" );
?>

IUserInterface defines what operations a user object should perform.IUserIs calledUser,UserFactoryThe factory class is created.IUserObject. This relationship can be expressed in UML in figure 1.


Figure 1. factory class and related IUser interface and user class


If you usephpThe interpreter runs the code on the command line and returns the following results:

% php factory1.php 
Jack
%

The test code will request the factoryUserObject and outputgetNameResult of the method.

There is a variation in the factory model that uses the Factory method. Class. This method is useful when you create an object of this type. For example, suppose you need to create an object first and then set many attributes. The factory mode of this version encapsulates the process in a single location, so that you do not need to copy complicated initialization code or paste the copied code everywhere in the code base.

Listing 2 shows an example of using the factory method.


Listing 2. Factory2.php
     interface IUser
{
function getName();
}

class User implements IUser
{
public static function Load( $id )
{
return new User( $id );
}

public static function Create( )
{
return new User( null );
}

public function __construct( $id ) { }

public function getName()
{
return "Jack";
}
}

$uo = User::Load( 1 );
echo( $uo->getName()."\n" );
?>

This code is much simpler. It has only one interfaceIUserAndUserClass.UserClass has two static methods for creating objects. This link can be expressed in UML in figure 2.


Figure 2. IUser interface and user class with factory method


The result of running the script in the command line is the same as that in listing 1, as shown below:

% php factory2.php 
Jack
%

As mentioned above, sometimes such models seem to be a little useful in a small environment. However, it is best to learn this solid coding format to apply it to any scale of projects.

Single element mode

Some application resources areExclusiveBecause there is only one resource of this type. For example, the connection from a database handle to a database is exclusive. You want to share the database handle in the application, because it is an overhead when you keep the connection open or closed, especially when you get a single page.

The single-element mode can meet this requirement. If an application contains only one object at a time, this object isSingle element(Singleton ). The code in listing 3 shows a single database connection element in PHP V5.


Listing 3. Singleton. php
     require_once("DB.php");

class DatabaseConnection
{
public static function get()
{
static $db = null;
if ( $db == null )
$db = new DatabaseConnection();
return $db;
}

private $_handle = null;

private function __construct()
{
$dsn = 'mysql://root:password@localhost/photos';
$this->_handle =& DB::Connect( $dsn, array() );
}

public function handle()
{
return $this->_handle;
}
}

print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
?>

This code displays the nameDatabaseConnection. You cannot create your ownDatabaseConnectionBecause constructors are dedicated. But staticgetMethod, you can obtain and only obtain oneDatabaseConnectionObject. This code is shown in UML 3.


Figure 3. database connection ticket elements


Between two calls,handleThe database handle returned by the method is the same, which is the best proof. You can run the code in the command line to observe this point.

% php singleton.php 
Handle = Object id #3
Handle = Object id #3
%

The two handles returned are the same object. If you use a single database connection element in the entire application, you can reuse the same handle anywhere.

You can use global variables to store database handles. However, this method is only applicable to small applications. In large applications, avoid using global variables and use objects and methods to access resources.

Observer Mode

The Observer Mode provides another way to avoid close coupling between components. This mode is very simple: an object is allowed by adding a method (this method allows another object, that isObserverRegister yourself. When an observed object changes, the message is sent to the registered observer. The operations performed by these observers using this information are irrelevant to the observed objects. The result is that objects can communicate with each other without understanding the cause.

A simple example is the user list in the system. The code in listing 4 shows a user list. when a user is added, it sends a message. When a user is added, the list can be observed by the log observer who sends the message.


Listing 4. Observer. php
     interface IObserver
{
function onChanged( $sender, $args );
}

interface IObservable
{
function addObserver( $observer );
}

class UserList implements IObservable
{
private $_observers = array();

public function addCustomer( $name )
{
foreach( $this->_observers as $obs )
$obs->onChanged( $this, $name );
}

public function addObserver( $observer )
{
$this->_observers []= $observer;
}
}

class UserListLogger implements IObserver
{
public function onChanged( $sender, $args )
{
echo( "'$args' added to user list\n" );
}
}

$ul = new UserList();
$ul->addObserver( new UserListLogger() );
$ul->addCustomer( "Jack" );
?>

This code defines four elements: two interfaces and two classes.IObservableInterface defines objects that can be observed,UserListThis interface is implemented to register itself as an observer.IObserverThe list defines how to become an observer,UserListLoggerImplementationIObserverInterface. The elements are shown in UML in figure 4.


Figure 4. observed user list and user list event log programs


If you run it in the command line, you will see the following output:

% php observer.php 
'Jack' added to user list
%

Test code creationUserList, AndUserListLoggerAdd the observer to it. Then add a consumer and notify the changeUserListLogger.

RecognizeUserListIt is critical to know what operations the log program will perform. One or more listeners may execute other operations. For example, you may have an observer who sends messages to a new user. You are welcome to use this system. The value of this method lies inUserListIgnore all objects dependent on it. it focuses on maintaining the user list and sending messages when the list is changed.

This mode is not limited to objects in memory. It is the basis for database-driven message query systems used in large applications.

Command chain mode

Command chainThe mode sends messages, commands, and requests based on loosely coupled topics, or sends arbitrary content through a set of handlers. Each handler determines whether it can process the request. If yes, the request is processed and the process stops. You can add or remove a handler for the system without affecting other handlers. Listing 5 shows an example of this mode.


Listing 5. Chain. php
     interface ICommand
{
function onCommand( $name, $args );
}

class CommandChain
{
private $_commands = array();

public function addCommand( $cmd )
{
$this->_commands []= $cmd;
}

public function runCommand( $name, $args )
{
foreach( $this->_commands as $cmd )
{
if ( $cmd->onCommand( $name, $args ) )
return;
}
}
}

class UserCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'addUser' ) return false;
echo( "UserCommand handling 'addUser'\n" );
return true;
}
}

class MailCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'mail' ) return false;
echo( "MailCommand handling 'mail'\n" );
return true;
}
}

$cc = new CommandChain();
$cc->addCommand( new UserCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addUser', null );
$cc->runCommand( 'mail', null );
?>

This code defines maintenanceICommandObject ListCommandChainClass. Both classes can be implemented.ICommandInterface-one responds to the email request and the other responds to the added user. Figure 5 shows the UML.


Figure 5. command chain and related commands


If you run a script containing some test code, the following output is displayed:

% php chain.php 
UserCommand handling 'addUser'
MailCommand handling 'mail'
%

The code is first createdCommandChainAnd add instances of two command objects for it. Then run two commands to check who has responded to these commands. If the command name matchesUserCommandOrMailCommandThe code fails without any operation.

When creating a scalable architecture for request processing, the command chain mode is very valuable and can solve many problems.

Rule mode

The last design pattern we talk about isPolicyMode. In this mode, algorithms are extracted from complex classes and can be easily replaced. For example, if you want to change the page arrangement method in the search engine, the policy mode is a good choice. Think about the several parts of the search engine-one part traverses the page, the other part sorts each page, and the other part sorts the results based on the arrangement. In a complex example, these parts are in the same class. By using the policy mode, you can place the arranged parts into another class to change the page arrangement method without affecting the rest of the search engine code.

As a simple example, listing 6 shows a user list class, which provides a method for finding a group of users based on a set of plug-and-play policies.


Listing 6. Strategy. php
     interface IStrategy
{
function filter( $record );
}

class FindAfterStrategy implements IStrategy
{
private $_name;

public function __construct( $name )
{
$this->_name = $name;
}

public function filter( $record )
{
return strcmp( $this->_name, $record ) <= 0;
}
}

class RandomStrategy implements IStrategy
{
public function filter( $record )
{
return rand( 0, 1 ) >= 0.5;
}
}

class UserList
{
private $_list = array();

public function __construct( $names )
{
if ( $names != null )
{
foreach( $names as $name )
{
$this->_list []= $name;
}
}
}

public function add( $name )
{
$this->_list []= $name;
}

public function find( $filter )
{
$recs = array();
foreach( $this->_list as $user )
{
if ( $filter->filter( $user ) )
$recs []= $user;
}
return $recs;
}
}

$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );
$f1 = $ul->find( new FindAfterStrategy( "J" ) );
print_r( $f1 );

$f2 = $ul->find( new RandomStrategy() );
print_r( $f2 );
?>

This code is shown in UML 6.


Figure 6. user list and user selection policy


UserListClass is a package of the name array. It implementsfindMETHOD. this method selects a subset of these names using one of several policies. These policies are composedIStrategyInterface definition. this interface has two implementations: one randomly selects a user and the other selects all the subsequent names based on the specified name. When you run the test code, the following output is displayed:

% php strategy.php 
Array
(
[0] => Jack
[1] => Lori
[2] => Megan
)
Array
(
[0] => Andy
[1] => Megan
)
%

The test code runs the same user list for two policies and displays the results. In the first case, the rule search is arranged inJAnd you will get Jack, Lori, and Megan. The second policy selects a random name and produces different results each time. In this case, the result is Andy and Megan.

The rule mode is very suitable for complex data management systems or data processing systems. The two require high flexibility in data filtering, search, or processing methods.

Conclusion

This article only describes several of the most common design patterns used in PHP applications. InDesign ModeThe book demonstrates more design patterns. Do not give up because the architecture is mysterious. Pattern is a wonderful concept, applicable to any programming language, any skill level.

The Design patterns are introduced into the software community by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Design (commonly known as the "Gang of Four "). Introduction...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.