Home >Backend Development >PHP Tutorial >Twelve design patterns in PHP_PHP tutorial

Twelve design patterns in PHP_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 09:51:47897browse

Twelve design patterns of PHP

Design basis of PSR-0 specification
1. Use namespaces for everything
2. All php files must be loaded automatically without include/require
spl_autoload_register
3.Single entrance mode




1. Three basic design patterns
Factory mode
Use a factory method to replace a new


class Factory{

static function createDatabase(){
$db = new Database;
return $db;
}
}
When using it, you can use $db = Factory::createDatabase();




Singleton pattern
class Database{
private $db;


private function __construct(){
//Here you can write to connect to the database
}


static function getInstance(){
if(self::$db){
return self::$db;
}else{
self::$db=new self()
return self::$db;//private can call itself
}
}


function where(){




}


}


If it is a factory plus singleton mode
class Factory{

static function createDatabase(){
$db = Database::getInstance();
return $db;
}
}


Registrar (tree) mode
class Register{
protected static $object;
static function set($alias,$object){
self::$object[$alias]=$object;


}
static function get($name)
{
return self::$object[$name];
}
function _unset($alias){
unset(self::$object[$alias]);
}
}
Combined with factory methods
class Factory{

static function createDatabase(){
$db = Database::getInstance();
Register::set('db1',$db);
return $db;
}
}
Index calls directly
$db = Register::get('db1');


Adapter Pattern
1. Adapter mode can encapsulate completely different functional interfaces into a unified API
2. Practical application examples, PHP database operations include mysql, mysqli, and pdo. You can use the adapter mode
Unify into consistency, similar scenarios include cache adapters, which unify different cache functions such as memcache, redis, file, apc, etc. into consistency,
For example, there is an interface in Database.php
interface IDatabase
{
function connect($host,$user,$pwd,$dbname);
function query($sql);
function close();
}


There are three categories below
class mysql implements IDatabase{
private $con;
function connect($host,$user,$pwd,$dbname){
$this->con = mysql_connect($host,$user,$pwd);
mysql_select_db($dbname,$this->con);
}
function query($sql){
return mysql_query($sql,$this->con);
}
function close(){
return mysql_close($this->con);
}
}


class mysqli implements IDatabase{
protected $con;
function connect($host,$user,$pwd,$dbname)
{
$this->con = mysqli_connect($host,$user,$pwd,$dbname);
}
function query($sql)
{
return mysqli_query($this->con,$sql);
}
function close()
{
return mysqli_close($this->con);
}
}


class PDO implements IDatabase{
protected $con;
function connect($host,$user,$pwd.$dbname)
{
$con = new PDO("mysql:host=$host;dbname=$dbname",$user,$pwd);
$this->con=$con;
}
function query($sql){
return $this->con->query($sql);
}
function close(){
unset($this->con);
}
}
In this way when we call
$db = new mysql(); or new mysqli(); or new PDO();
$db->connect('127.0.0.1','root','root');
$db->query();
$db->close();


Strategy Mode
Encapsulate a specific set of behaviors and algorithms into classes to adapt to certain specific contexts. This pattern is the strategy pattern
Practical application distance, if an e-commerce website system requires male and female users to jump to different product categories
First declare a strategy interface file
interface UserStrategy{
function showAd();
function showcategory();
}


//The first strategy is for female users
class femaleUserStrategy implements UserStrategy{
function showAd(){
echo '2014 new women's clothing';
}
function showCategory()
{
echo 'women's clothing';
}
}
//The second strategy is for male users
class maleUserStrategy implements UserStrategy{
function showAd(){
echo '2014 new men's clothing';
}
function showCategory()
{
echo 'men's clothing';
}
}
//If there is a page class
class page{
protected $strategy;
function index(){
$this->strategy->showAd();
$this->strategy->showCategory();
}


function setStrategy(UserStrategt $strategy){
$this->strategy=$strategy;
}
}
$page = new Page();
if(isset($_GET['female'])){
$strategy = new femaleUserStrategy();
}else{
$strategy = new maleUserStrategy();
}
$page->setStrategy($strategy);
$page->index();
From a hard-coded to decoupled pattern


Data Object Mapping Pattern
The data object mapping mode maps objects and data storage to a
Object operations are mapped to operations on the data store.
To implement the data object mapping mode in code, we will implement an ORM class to map complex SQL statements into object attribute operations
class User{
public $id;
public $name;
public $mobile;
public $regtime;
protected $db;
function __construct($id){
//Get data first
$this->db = new mysql();
$this->db->connect('xxxxx'xxxx);
$res = $this->db->query('select * from XXX where id = {$id}');
$data = $res->fetch_assoc();


$this->id=$data['id'];
$this->name=$data['name'];
$this->mobile=$data['mobile'];
$this->regtime=$data['regtime'];
return $res;
}


function __destruct(){
//Can be used as a modification
$this->db->query('update xx set name={$this->name} mobile={$this->mobile}XXXXX where id = {$this->id}');
}
}


$user = new User(1);//1 corresponds to the id in the database being one
$user->mobile = '155555555';
$user->name='test';
$user->regtime=time();
//There are no sql statements here. Only operations on objects


Comprehensive application (factory mode, registrar mode, adapter mode)


with
Observer Mode
1. Observer pattern, when the state of an object changes, all objects that depend on it will receive notifications and automatically update.
2. Scenario: After an event occurs, a series of update operations need to be performed. The traditional programming method is
The processing logic is added directly after the event code. When the updated logic increases, the code will become difficult to maintain. This method is coupled and intrusive,
Adding heart logic requires modifying the code of the event body
3. The observer pattern implements a low-coupling, non-intrusive notification update mechanism.
demo
class Event{
function trigger(){
echo "Event";//Indicates that an event occurred


//Start writing update logic
echo 'logical 1';

echo 'Logic 2';


echo 'logic 3';


}
}


$event = new Event();//The traditional method is coupled and intrusive,
//The source code must be changed, so we define an observer pattern
demo
//Here comes an interface
//First come a base abstract class
abstract class EventGenerator{
private $observers = array();
function addObserver(Observer$observer){
$this->obervers[]=$oberver;
}
function notify(){
foreach($this->obervers as $observer)
{
$observer->updata();
}
}
}
interface Oberver{
function update($event_info = null);
}
//So at this time we need the Event class to inherit this base class
class Event extends EventGenerator{
function trigger(){
echo "Event";//Indicates that an event occurred
$this->notify();
}
}


class Observer1 implements Observer{
function updata($event_info=null)
{
echo "Logic one";
}
}


class Oberver2 implements Oberver{
function updata($event_info=null)
{
echo "Logic 2";
}
}




Prototype Mode
1. Similar to the factory mode, it is used to create objects
2. Different from the implementation of factory mode, prototype mode first creates a prototype
Object, and then create a new object by cloning the prototype object, thus eliminating the need for classes
Repeated initialization operations during creation
3. The prototype mode is suitable for the creation of large objects. Creating a large object requires a lot of overhead. If it is new every time, it will consume a lot of money,
Prototype mode only copies memory.
Suppose there is a canvas class. new is complicated
I want to use him twice more
In this way, we can use prototype mode to solve the problem of new and use clone to replace new
Just clone it directly after initialization.


Decorator Pattern
1. Decorator mode can dynamically add and modify class functions.
2. A class provides a function. If you want to modify and add additional functions, the traditional
In programming mode, you need to write a subclass to inherit it and reimplement the class methods.
3. Using the decorator mode, you only need to add a decorator object at runtime to achieve maximum flexibility
If we have a canvas class. Only one square can be printed, if we want to add a color
Generally, you write a subclass and inherit that canvas class.
Override the method that generates the canvas.So what if we want to add a lot of functions?
Do I need to rewrite many classes?
Next we use the decorator pattern to solve this problem
First, let’s declare a canvas decorator interface
interface DrawDecorator{
function beforeDraw();
function afterDraw();
}


For example, we need to modify the draw() method of the canvas class
So we call
in the draw() method function draw(){
$this->beforeDraw();
//Here is the content of the original code
$this->afterDraw();
}
Then add a protected $decorators[]=array();
in the canvas class Add a method to receive the decorator interface
function addDecorator(DrawDecorator $decorator){
$this->decorators[]=$decorator;
}
Add two more methods to call the decorator
function beforeDraw(){
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}


function afterDraw(){
//Reverse, last in first out
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}


We have a color decorator
class ColorDrawDecorator implements DrawDecorator{
protected $color;
function __construct($color='red')
{
$this->color= $color;
}
function beforeDraw()
{
echo "
";
}
function afterDraw()
{
echo "
"
}
}
There is no need to inherit to implement it here
$a = new canvas();//Instantiate the canvas class
$a -> init();//Initialization
$a -> addDecorator(new colorDrawDecorator('green'));//Add a color decorator class
Iterator Pattern
1. Iterator mode, traverse yige
without knowing the internal implementation Internal elements of aggregate objects
2. Compared with traditional programming patterns, the iterator pattern can hide the operations required to traverse elements
For example, traverse a database and get all objects
class Alluser implements Iterator{
protected $ids;
protected $index;//current position of iterator
protected $data=array();
//Iterator is the iterator interface
function __construct(){
$db = Factory::getDatabase();
$result = $db->query("selecy id from user");
$this->ids = $db->mysql_fetch_assoc($result);
}
function current(){
//Get the current element
$id=$this->ids[$this->index]['id'];
return Factory::getUser($id);
}
function next(){
//Next element
$this->index ++;
}
function valid()
{
//Determine whether there is data
return $this->index ids);
}
function rewind(){
$this->index=0;//The first step to the beginning
}
function key(){
//Get the current index
return $this->index;
}
}
$users = new Alluser();
foreach ($users as $user)
{
var_dump($user);
}
Proxy mode
1. Establish a proxy object (proxy) between the client and the entity. The client delegates all operations on the entity to the proxy object, hiding the specific implementation details of the entity.
Just write a


Basic principles of object-oriented programming
1. Single responsibility: a class only needs to do one thing
2. Open and closed: a class should be extensible but not modifiable
3. Dependency inversion: A class should not be strongly dependent on another class. Each class is replaceable for another class
4. Configuration: Use configuration as much as possible instead of hard coding.
5. Interface-oriented programming: You only need to care about the interface, not the implementation.


Principles of MVC architecture
Let’s first create a new Config object
$config = new Config(__DIR__.'/configs');
$config['controller'];


Then there is a Config class
class Config implements ArrayAccess{
//The ArrayAccess interface is a built-in interface, which means that array values ​​are allowed to be passed. There are four methods to be implemented
protected $path;
protected $configs=array();
function __construct($path)
{
$this->path=$path;
}
function offsetGet($key){
//Get the configuration array file name key
if(empty($this->configs[$key]))
//If the array file name does not exist in the original configuration file, then load it
{
$file_path=$this->path.'/'.$key.'.php';//Generate loading path
$config = require $file_path;
$this->config[$key]=$config;
}
return $this->configs[$key];


}
function offsetSet($key,$value)
{
//Set the key of the array
}
function offsetExists($key)
{ //Check whether the key of the array exists
return isset($this->configs[$key]);
}
function offsetUnset($key)
{ //Delete the key of the array

}
}


Configuration files such as controller.php
$config = array(
'home'=>array(
'decorator'=>array(
'IMoocDectoratorTemplate',
),
),
);


Configuration and Design Patterns
1. Use ArrayAccess in PHP to load configuration files
2. Read the configuration in the factory method and generate a configurable object
3. Use the decorator mode to implement permission verification, template rendering, and json serialization
4. Use the observer pattern to implement a series of update operations for data update events
5. Use proxy mode to implement automatic master-slave switching of the database

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1011354.htmlTechArticleThe design basis of the PHP twelve design patterns PSR-0 specification 1. All use namespaces 2. All php files Must be loaded automatically, no include/require spl_autoload_register 3. Single entry mode...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn