Introduction to design patterns commonly used in PHP and example usage

Source: Internet
Author: User
Tags php and mysql php database
The PHP namespace can better organize your code, similar to a package in Java.

Test1.php<?phpnamespace test1;//namespace Test1function Test () {    echo __file__;} Test2.php<?phpnamespace Test2; Namespace Test2function Test () {    echo __file__;//prints the absolute path where the current file is located. }test.php<?phprequire ' test1.php '; require ' test2.php '; Test1\test ();//In this way, the method or class under the namespace is used. Test1 represents a namespace, and test () represents a method under that namespace. echo "<br>"; Test2\test ();

Run results

Summary: With the above code, you can see that under different namespaces, you can have the same class name or method name.

Class Auto-onboarding

As the PHP project becomes larger, it causes a lot of require in front of a PHP file to contain various dependent PHP files. If a class is deleted, but there is an import in another file, it can cause a fatal error. The way to solve the above problem is the __autoload () function.

Test1.php<?phpclass test1{    static function test () {        echo __file__;    }} Test2.php<?phpclass test2{    static function test () {        echo __file__;    }} Test.php<?phptest1::test (); Test2::test (); function __autoload ($class) {    $dir  = __dir__;    $requireFile = $dir. " \ \ ". $class.". PHP ";    Require $requireFile;}

PHP is using this code to dynamically load the files that need to be included. When a class is used, and the class is not included in the file, the __autoload () function is called to dynamically load the file. However, when multiple frames are used, each frame will have its own __autoload () implementation, which causes the file to be imported repeatedly.

<?phpspl_autoload_register (' Autoload1 '); Spl_autoload_register (' autoload2 ');//will implement auto-import functions, in the form of a string into the function, To resolve errors caused by duplicate import files. Test1::test (); Test2::test (); function Autoload1 ($class) {    $dir  = __dir__;    $requireFile = $dir. " \ \ ". $class.". PHP ";    Require $requireFile;} function Autoload2 ($class) {    $dir  = __dir__;    $requireFile = $dir. " \ \ ". $class.". PHP ";    Require $requireFile;}

PSR-0

    1. The namespace of PHP must match the absolute path.

    2. The first letter of the class name is capitalized.

    3. In addition to the portal file, the other PHP file must be a class and cannot have code to execute.

Design Patterns

The singleton pattern solves the problem of how to create a unique object instance throughout the project, and the factory pattern solves the method of not building the instance object through new.

Single-Case mode

    1. $_instance must be declared as a static private variable

    2. Constructors and destructors must be declared private to prevent the external program new class from losing the meaning of the singleton pattern

    3. The getinstance () method must be set to public, and this method must be called to return a reference to the instance

    4. :: operator can access static and static functions only

    5. New objects will consume memory

    6. Usage Scenario: The most common place is the database connection.

    7. Once an object is generated using singleton mode, the object can be used by many other objects.

    8. Private __clone () method prevents cloning of objects

Singleton mode, which allows an object of a class to create only one. constructor private decoration,
Declare a static GetInstance method that creates an instance of the object in the method. If the instance already exists, it is not created. For example, you only need to create a database connection.

Factory mode

Factory mode, factory method, or class generates objects instead of directly new in code.
With Factory mode, you can avoid changing the name or method of a class by modifying its name or parameter in all the code that calls the class.

Test1.php<?phpclass test1{    static function test () {        echo __file__;    }} Factory.php<?phpclass factory{    /     * * If a class is new ClassName () in many files, then in case the class name     * Changes or the parameters change, If you do not use the Factory mode, you need to modify each PHP     * code, using the Factory mode, only need to modify the factory class or method.     *    /static function CreateDatabase () {        $test = new Test1 ();        return $test;    }} Test.php<?phpspl_autoload_register (' Autoload1 '); $test = Factory::createdatabase (); $test->test (); function Autoload1 ($class) {    $dir  = __dir__;    $requireFile = $dir. " \ \ ". $class.". PHP ";    Require $requireFile;}

Test1.php<?phpclass test1{    protected static  $tt;    Private Function __construct () {}    static function getinstance () {        if (self:: $TT) {            echo "object has been created <br>";            Return self:: $tt;        } else {self            :: $tt = new Test1 ();            echo "Create object <br>";            Return self:: $tt;        }    }     function Echohello () {        echo "hello<br>";    }} Test.php<?phpspl_autoload_register (' Autoload1 '); $test = Test1::getinstance (); $test->echohello (); $test = Test1::getinstance (); $test->echohello (); $test = Test1::getinstance (); $test->echohello (); $test = Test1:: GetInstance (); $test->echohello (); function Autoload1 ($class) {    $dir  = __dir__;    $requireFile = $dir. " \ \ ". $class.". PHP ";    Require $requireFile;}

Registration mode

Register the mode to resolve global shares and swap objects. An object that has been created, hangs on a globally available array, and is fetched directly from the array when it is needed. Registers an object on the global tree. Anywhere directly to visit.

<?phpclass register{    protected static  $objects;    function set ($alias, $object)//Register the object to the global tree    {self        :: $objects [$alias]= $object;//Place the object on the tree    }    static function Get ($name) {        return self:: $objects [$name];//get an object registered to the tree    }    function _unset ($alias)    {        unset (self:: $objects [$alias]);//Remove an object registered to the tree.    }}

Adapter mode

Encapsulates a variety of distinct function interfaces into a unified API.
PHP database operation has mysql,mysqli,pdo three kinds, you can use the adapter mode unified into the same, so that different database operations, unified into the same API. A similar scenario also has the cache adapter, which unifies different cache functions such as MEMCACHE,REDIS,FILE,APC.
First define an interface (there are several methods, and the corresponding parameters). Then, there are several different situations in which you write several classes to implement the interface. Functions that accomplish similar functions are unified into a consistent approach.

Interface Idatabase<?phpnamespace imooc;interface idatabase{    function Connect ($host, $user, $passwd, $dbname);    function query ($sql);    function close ();}
Mysql<?phpnamespace Imooc\database;use Imooc\idatabase;class MySQL implements idatabase{protected    $conn;    Function Connect ($host, $user, $passwd, $dbname)    {        $conn = mysql_connect ($host, $user, $passwd);        mysql_select_db ($dbname, $conn);        $this->conn = $conn;    }    function query ($sql)    {        $res = mysql_query ($sql, $this->conn);        return $res;    }    function Close ()    {        mysql_close ($this->conn);}    }
Mysqli<?phpnamespace Imooc\database;use Imooc\idatabase;class mysqli implements idatabase{    protected $conn;    Function Connect ($host, $user, $passwd, $dbname)    {        $conn = Mysqli_connect ($host, $user, $passwd, $dbname); c20/> $this->conn = $conn;    }    function query ($sql)    {        return mysqli_query ($this->conn, $sql);    }    function Close ()    {        mysqli_close ($this->conn);}    }

Pdo<?phpnamespace Imooc\database;use Imooc\idatabase;class PDO implements idatabase{    protected $conn;    Function Connect ($host, $user, $passwd, $dbname)    {        $conn = new \pdo ("mysql:host= $host;d bname= $dbname", $user, $ passwd);        $this->conn = $conn;    } function query ($sql)    {        return $this->conn->query ($sql);    }    function Close ()    {        unset ($this->conn);}    }

Through the above case, PHP and MySQL database interaction has three sets of APIs, in different scenarios may use different APIs, then the development of good code, a change of environment, it may be necessary to change its database API, then rewrite all the code, after using the adapter mode, It is possible to use a unified API to mask the problem of rewriting the code after the environment changes caused by the underlying API differences.

Policy mode

A policy pattern that encapsulates a specific set of behaviors and algorithms into classes to accommodate specific contexts.
Eg: if there is an e-commerce website system, for male female users to jump to different product categories, and all advertising sites show different ads. In the traditional code, it is in the system to add a variety of if else judgment, hard-coded way. If one day you add a user, you need to rewrite the code. Using the policy mode, if you add a new user type, you only need to add one more policy. All other places just need to use a different strategy.
The interface file for the policy is declared first, and the contained behavior of the policy is contracted. Then, define each specific policy implementation class.

userstrategy.php<?php/* * Declares the interface of the policy file, and the behavior that the contract policy contains. */interface userstrategy{    function Showad ();    function showcategory ();}

Femaleuser.php<?phprequire_once ' loader.php '; class Femaleuser implements userstrategy{    function Showad () {        echo "2016 winter Ladies";    }    function Showcategory () {        echo ' ladies ';    }}

Maleuser.php<?phprequire_once ' loader.php '; class Maleuser implements userstrategy{    function Showad () {        echo "iphone6s";    }    function Showcategory () {        echo "electronic product";    }}

page.php//execution file <?phprequire_once ' loader.php '; class page{    protected $strategy;    function index () {        echo "AD";        $this->strategy->showad ();        echo "<br>";        echo "Category";        $this->strategy->showcategory ();        echo "<br>";    }    function Setstrategy (userstrategy $strategy) {        $this->strategy= $strategy;    }} $page = new page (), if (Isset ($_get[' male ')) {    $strategy = new Maleuser ();} else {    $strategy = new Femaleuser ();} $page->setstrategy ($strategy); $page->index ();

Execution result diagram:


Summarize:
In this way, you can find that different users sign in, but the hard-coded problem is resolved when the display is displayed. If you want to add a strategy, you only need to add a policy implementation class, and then execute the judgment in the portal file and pass in the class. Achieve understanding decoupling.
Implement dependency inversion and control inversion (to be understood)
By means of interfaces, the classes and classes are not directly dependent on each other. When the class is used, only one implementation class of the interface is dynamically passed in. If you want to replace a class, you only need to provide an implementation class that implements the interface, and the substitution is done by modifying one line of code.

Observer pattern

1: Observer mode (Observer), when an object state changes, all objects that depend on it are notified and updated automatically.
2: Scene: After an event occurs, a series of update operations are performed. The traditional way of programming is to add the processing logic directly after the code of the event. When the logic of updates increases, the code becomes difficult to maintain. This approach is coupled, intrusive, and adds new logic to the body code that needs to modify the event.
3: The Observer pattern realizes a low-coupling, non-intrusive notification and update mechanism.
Defines an event-triggering abstract class.

Eventgenerator.php<?phprequire_once ' loader.php '; abstract class eventgenerator{    Private $observers = Array ();    function Addobserver (Observer $observer) {        $this->observers[]= $observer;    }    function Notify () {        foreach ($this->observers as $observer) {            $observer->update ()}        }    }

Define an Observer interface

Observer.php<?phprequire_once ' loader.php '; interface observer{    function Update ();//This is the logic to execute after the event has occurred}

<?php//A class that implements the Eventgenerator abstract class, which is used to define an event require ' loader.php '; class Event extends eventgenerator{    function Triger () {        echo "event<br>";    }} Class Observer1 implements observer{    function Update () {        echo "logic 1<br>";    }} Class Observer2 implements observer{    function Update () {        echo "logic 2<br>";    }} $event = new Event (), $event->addobserver (New Observer1 ()), $event->addobserver (New Observer2 ()), $event Triger (); $event->notify ();

When an event occurs, the logic that needs to be executed increases, and the logic is loosely coupled. That is the red part of the code, you just need to define a class that implements the observer interface, implement complex logic, and then add a line of code to the red part. This achieves a low coupling.

Prototype mode

Prototype mode (object cloning to avoid consumption when creating objects)
1: Similar to Factory mode, it is used to create objects.
2: Unlike Factory mode implementations, the prototype pattern is to create a good one prototype object and then create a new object from the Clone prototype object. This eliminates the repetitive initialization of class creation.
3: Prototype mode is suitable for large object creation, creating a large object requires a lot of overhead, and if new is consumed very much, the prototype mode only needs a memory copy.

Canvas.php<?phprequire_once ' loader.php '; class canvas{private $data; function init ($width = $height = ten)    { c1/> $data = Array ();        for ($i = 0; $i < $height; $i + +)        {for            ($j = 0; $j < $width; $j + +)            {                $data [$i] [$j] = ' * ';            }        }        $this->data = $data;    } function rect ($x 1, $y 1, $x 2, $y 2)    {        foreach ($this->data as $k 1 + = $line)        {            if ($x 1 > $k 1 or $ X2 < $k 1) continue;           foreach ($line as $k 2 = $char)            {              if ($y 1> $k 2 or $y 2< $k 2) continue;                $this->data[$k 1][$k 2] = ' # ';    }} function Draw () {        foreach ($this->data as $line) {            foreach ($line as $char) {                echo $char;            }            echo "<br>;";}}    }

Index.php<?phprequire ' loader.php '; $c = new canvas (); $c->init ();/$canvas 1 = new canvas ();//$canvas 1->init (); $canvas 1 = clone $c;//by Cloning, the init () method can be omitted, and this method loops 200 times//to produce an array. When a lot of such objects need to be produced in a project, there will be many new objects, and/or are very performance-intensive. $canvas 1->rect (2, 2, 8, 8); $canvas 1->draw (); echo "-----------------------------------------<br>";//$ CANVAS2 = new Canvas ();//$canvas 2->init (); $canvas 2 = Clone $c; $canvas 2->rect (1, 4, 8, 8); $canvas 2->draw ();

Execution Result:

Adorner mode

1: Decorator mode, can dynamically add the ability to modify the class
2: A class provides a feature that, if you want to modify and add additional functionality to the traditional programming pattern, you need to write a subclass to inherit it and override the method of implementing the class

3: With adorner mode, you only need to add an adorner object at run time to achieve maximum amount of flexibility.

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.