PHP four design patterns

1php common development mode:

1. Single column mode

2. Factory mode

3. Observer pattern

4. Strategy mode

2 design pattern examples

1. Singleton mode

The singleton pattern, as the name suggests, means that there is only one instance. As an object creation mode, the singleton mode ensures that a certain class has only one instance, and instantiates itself and provides this instance to the entire system.

There are three main points of the singleton pattern:

One is that a class can only have one instance;

The second is that it must create this instance by itself;

The third is that it must provide this instance to the entire system by itself.

Why Use the PHP Singleton Pattern

  1. The application of php is mainly in the database application. There will be a large number of database operations in an application. When developing in an object-oriented way, if you use the singleton mode, you can avoid a large number of resources consumed by new operations, and you can also reduce database connections. It is not easy to have too many connections.

  1. If a class is needed in the system to globally control certain configuration information, then it can be easily realized by using the singleton mode. For this, please refer to the FrontController part of zend Framework.

  1. In a page request, it is easy to debug, because all the codes (such as the database operation class db) are concentrated in one class, we can set hooks in the class and output logs, so as to avoid var_dump and echo everywhere.

example:

/**
 * Singleton mode of design mode
 * $_instance must be declared as a static private variable
 * The constructor must be declared as private to prevent the new class from the external program and thus lose the meaning of the singleton mode
 * The getInstance() method must be set to public and must be called to return a reference to the instance
 *::operator can only access static variables and static functions
 * new objects will consume memory
 * Usage scenario: The most commonly used place is database connection.
 * After using the singleton pattern to generate an object, the object can be used by many other objects.
 */
class man {
    //Save the example instance in this property
    private static $_instance;
    //The constructor is declared as private to prevent direct creation of objects
    private function __construct(){
        echo 'I was instantiated! '
    ;}
    //Singleton method
    public static function get_instance(){
        var_dump(isset(self::$_instance));
        if(!isset(self::$_instance)){
            self::$_instance=newself();
        }
    return self::$_instance;
    }
    //Prevent users from copying object instances
    private function __clone(){
        trigger_error('Clone is not allowed', E_USER_ERROR);
    }
        function test(){
            echo("test");
        }
    }
    // This way of writing will be wrong, because the constructor is declared as private
    //$test = new man;
    // The following will get the singleton object of the Example class
    $test = man::get_instance();
    
    $test->test();
    // Copying the object will result in an E_USER_ERROR.
    //$test_clone = clone $test;

2. Simple factory pattern

①Abstract base class: some abstract methods are defined in the class to be implemented in subclasses

②Subclass inherited from the abstract base class: implement the abstract method in the base class

③Factory class: used to instantiate all corresponding subclasses

 /**
     *
     * Define an abstract class and let subclasses inherit and implement it
     *
     */
     abstract class Operation{
        //Abstract methods cannot contain function bodies
         abstract public function getValue($num1,$num2);
        //It is strongly required that subclasses must implement this function
    }
    /**
      * Addition class
      */
     class OperationAdd extends Operation{
         public function getValue($num1,$num2){return $num1 + $num2;}
    }/**
      * Subtraction class
      */
     class OperationSub extends Operation{
         public function getValue($num1,$num2){return $num1-$num2;}
    }/**
      * Multiplication class
      */
     class OperationMul extends Operation{
         public function getValue($num1,$num2){return $num1*$num2;}
    }/**
      * Division class
      */
     class OperationDiv extends Operation{
         public function getValue($num1, $num2){
            try {
                if($num2==0){
                    thrownewException("The divisor cannot be 0");
                }else{
                    return $num1/$num2;
                }
            }catch(Exception $e){
                 echo "Error message:".$e->getMessage();
            }
        }
    }

By adopting the object-oriented inheritance feature, we can easily expand the original program, such as: ‘power’, ‘square root’, ‘logarithm’, ‘trigonometric function’, ‘statistics’, etc. Can avoid loading unnecessary code.

If we need to add a remainder class now, it will be very simple

We only need to write another class (this class inherits the virtual base class), complete the corresponding functions in the class (such as: calculation of power), and greatly reduce the degree of coupling, which is convenient for future maintenance and expansion

 /**
     * Remainder
     *
     */
    class OperationRem extends Operation{
        public function getValue($num1,$num2){return $num1%$num12;}}

Now there is still an unsolved problem, that is, how to let the program instantiate the corresponding object according to the operator input by the user?

Solution: use a separate class to implement the instantiation process, this class is the factory

 /**
     * Engineering class, mainly used to create objects
     * Function: According to the input operation symbol, the factory can instantiate the appropriate object
     *
     */
    class Factory{
        public static function createObj($operate){
            switch ($operate){
                case ' + ':returnnewOperationAdd();break;
                case '-':returnnewOperationSub();break;
                case '*':returnnewOperationSub();break;
                case '/':returnnewOperationDiv();break;
            }
        }
    }
    $test=Factory::createObj('/');
    $result=$test->getValue(23,0);
    echo $result;

Other notes about this mode:

Factory pattern:

Take the vehicle as an example: please customize the vehicle and the production process of the vehicle

1> Customized vehicles

1. Define an interface, which contains the method of delivery tool (start run stop)

2. Let airplanes, cars and other classes realize them

2> Customized factory (similar to above)

1. Define an interface, which contains the manufacturing method of the delivery tool (start, run, stop)

2. Write factory classes for manufacturing airplanes and cars respectively to inherit and implement this interface

Original address: http://bbs.phpchina.com/thread-242243-1-1.html

3. Observer pattern

The Observer pattern is a behavioral pattern that defines a one-to-many dependency relationship between objects, so that when the state of an object changes, all objects that depend on it are notified and refreshed automatically. It perfectly separates observer objects from observed objects. A list of dependencies (observers) interested in a principal can be maintained in a separate object (principal). Have all observers each implement a common Observer interface to remove the direct dependency between the subject and the dependent object. (I can’t understand anyway)

Used spl (standard PHP library)

class MyObserver1 implements SplObserver{
    public functionupdate(SplSubject $subject){
        echo __CLASS__ .' - '. $subject->getName();}}

class MyObserver2 implements SplObserver{
    public functionupdate(SplSubject $subject){
        echo __CLASS__ .' - '. $subject->getName();}}

class MySubject implements SplSubject{
    private $_observers;
    private $_name;

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

    public function attach(SplObserver $observer){
        $this->_observers->attach($observer);}

    public function detach(SplObserver $observer){
        $this->_observers->detach($observer);}

    public function notify(){
        foreach ($this->_observers as $observer){
            $observer->update($this); }}

    public function getName(){return $this->_name;}}

$observer1 = newMyObserver1();
$observer2 = newMyObserver2();

$subject =newMySubject("test");

$subject->attach($observer1);
$subject->attach($observer2);

$subject->notify();

Reference text: http://www.php.net/manual/zh/class.splsubject.php

4. Strategy mode

In this pattern, algorithms are extracted from complex classes so they can be easily replaced. For example, if you want to change the way pages are ranked in a search engine, the Strategy pattern is a good choice. Think of the parts of a search engine — one that traverses pages, one that ranks each page, and another that ranks results based on the ranking. In complex examples, these parts are all in the same class. By using the strategy pattern, you can put the arrangement part into another class, so that you can change the way the pages are arranged without affecting the rest of the search engine’s code.

As a simpler example, a user list class is shown below that provides a method for finding a set of users based on a set of plug-and-play policies

//Define the interface
interface IStrategy{functionfilter($record);}//implement interface method 1
class FindAfterStrategy implements IStrategy{
    private $_name;
    public function__construct($name){
        $this->_name = $name;}
    public functionfilter($record){return strcmp ( $this->_name, $record )<=0;}}//implement interface method 1
class RandomStrategy implements IStrategy{
    public functionfilter($record){return rand (0,1)>=0.5;}}//main class
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 =newUserList( array ("Andy","Jack","Lori","Megan"));
$f1 = $ul->find (newFindAfterStrategy("J"));
print_r( $f1 );

$f2 = $ul->find(newRandomStrategy());

print_r( $f2 );

The Strategy pattern is well suited for complex data management systems or data processing systems that require a high degree of flexibility in how data is filtered, searched, or processed

Original address: http://blog.csdn.net/xujingzhong0077/article/details/53316562