PHP 12 Design Patterns
The design basis of PSR-0 specification
1. Use all namespaces
2. All PHP files must be loaded automatically, cannot have Include/require
Spl_autoload_register
3. Single entry mode
1. Three basic design Patterns
Factory mode
To replace a new one with a factory method
Class factory{
static function CreateDatabase () {
$db = new Database;
return $db;
}
}
Use the time can use $db = Factory::createdatabase ();
Single-Case mode
Class database{
Private $db;
Private Function __construct () {
You can write a connection database here
}
static function getinstance () {
if (self:: $db) {
Return self:: $db;
}else{
Self:: $db =new self ()
Return self:: $db;//private can invoke itself
}
}
function where () {
}
}
If it's a factory plus a 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 mode
1. Adapter mode, which can encapsulate a completely different function interface into a unified API
2. Practical application example, PHP database operation has MYSQL,MYSQLI,PDO3 type, can be used in adapter mode
Unified into the same, similar scenes also have the cache adapter, the MEMCACHE,REDIS,FILE,APC and other different cache functions, unified into a consistent,
For example, there is a database.php inside an interface
Interface Idatabase
{
Function Connect ($host, $user, $pwd, $dbname);
function query ($sql);
function Close ();
}
There are three more classes 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;d bname= $dbname", $user, $pwd);
$this->con= $con;
}
function query ($sql) {
return $this->con->query ($sql);
}
function Close () {
unset ($this->con);
}
}
So when we call,
$db = new MySQL (), or new mysqli (); or new PDO ();
$db->connect (' 127.0.0.1 ', ' root ', ' root ');
$db->query ();
$db->close ();
Policy mode
Encapsulates a specific set of behaviors and algorithms into classes to accommodate certain context contexts, which are policy patterns
Actual application distance, if an e-commerce system of the website system, for male female users to each jump to different product categories
First declare the interface file for a policy
Interface userstrategy{
function Showad ();
function Showcategory ();
}
The first strategy for female users
Class Femaleuserstrategy implements userstrategy{
function Showad () {
Echo ' 2014 new ladies ';
}
function Showcategory ()
{
echo ' Ladies ';
}
}
A second strategy for male users
Class Maleuserstrategy implements userstrategy{
function Showad () {
Echo ' 2014 new menswear ';
}
function Showcategory ()
{
echo ' menswear ';
}
}
If you have 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 mode
The data object mapping pattern is the mapping of objects and data stores to a
The operation of the object is mapped to the operation on the data store.
Implementing the data Object mapping pattern in code, we will implement an ORM class that maps complex SQL statements into object properties.
Class user{
public $id;
Public $name;
Public $mobile;
Public $regtime;
protected $db;
function __construct ($id) {
Fetch 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 the corresponding database has an ID of
$user->mobile = ' 155555555 ';
$user->name= ' test ';
$user->regtime=time ();
There are no SQL statements here. Only actions on objects
Integrated Application (Factory mode, Registrar mode, adapter mode)
And
Observer pattern
1. Observer mode, when an object state changes, all dependent objects are notified and updated automatically.
2. Scenario: After an event occurs, to perform a series of update operations, the traditional way of programming,
is to add the processing logic directly after the code of the event, and when the updated logic increases, the code becomes difficult to maintain, in a way that is coupled, intrusive,
Increase the logic of the heart needs to modify 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 has occurred
Start to write the update logic
echo ' logic 1 ';
echo ' Logic 2 ';
Echo ' Logic 3 ';
}
}
$event = new event ();//The traditional way is coupled, intrusive,
We have to change the source, so we define an observer pattern.
Demo
In an interface.
First, a base class. 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 this time we need the event class to inherit the base class.
Class Event extends eventgenerator{
Function trigger () {
echo "event";//indicates that an event has 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 II";
}
}
Prototype mode
1. Similar to the Factory mode, it is used to create objects
2. Unlike the implementation of the factory model, prototype mode first creates the good one prototype
Object, and then creates a new object from the Clone prototype object, eliminating the class
Duplicate initialization operation at creation time
3. Prototype mode is suitable for large object creation, it takes a lot of overhead to create a large object, and if new is consumed very much,
Prototype mode only copies memory.
If there is a canvas class. New is complicated.
I want to use him two times.
So that we can solve the new problem with the prototype model and replace the new with clone.
Clone directly after initialization.
Adorner mode
1. Decorator mode, you 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, the traditional
Programming mode, you need to write a subclass to inherit him, and re-implement the method of the class.
3. Using the adorner mode, only need to add an adorner object at run time, can achieve maximum flexibility
If we have a canvas class. Only one square can be printed, if we want to add a color
Usually write a subclass, inherit that canvas class.
Override the method that produces the canvas. So what if we're going to add a lot of features?
Do you want to rewrite many classes?
Let's use decorator mode to solve this problem.
First we declare the interface of a canvas decorator
Interface drawdecorator{
function Beforedraw ();
function Afterdraw ();
}
For example, we want to modify the draw () method of the canvas class
So we call in the draw () method
function Draw () {
$this->beforedraw ();
Here is the contents of the original code
$this->afterdraw ();
}
Then add a protected $decorators []=array () in the canvas class;
Adding a method to receive the adorner interface
function Adddecorator (Drawdecorator $decorator) {
$this->decorators[]= $decorator;
}
Add two more methods to call adorners
function Beforedraw () {
foreach ($this->decorators as $decorator)
{
$decorator->beforedraw ();
}
}
function Afterdraw () {
Reverse, LIFO
$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 Befordraw ()
{
echo "COLOR}; ' > ";
}
function Afterdraw ()
{
echo ""
}
}
There is no need to inherit to achieve it.
$a = new canvas ();//Instantiate Canvas class
$a, init ();//initialization
$a-adddecorator (new Colordrawdecorator (' green '));//Add a color to the adorner class
Iterator mode
1. Iterator mode, traversing yige without needing to know the internal implementation
The inner element of the aggregation object
2. The iterator pattern hides the required actions to traverse the elements compared to the traditional programming pattern
Like traversing a database and getting all the objects
Class AllUser implements iterator{
protected $ids;
protected $index;//iterator current position
Protected $data =array ();
Iterator is an iterator interface
Fucntion __construct () {
$db = Factory::getdatabase ();
$result = $db->query ("Selecy ID from user");
$this->ids = $db->mysql_fetch_assoc ($result);
}
function current () {
Gets the current element
$id = $this->ids[$this->index][' id '];
Return Factory::getuser ($id);
}
function Next () {
Next element
$this->index + +;
}
function valid ()
{
Determine if there is data
Return $this->index < count ($this->ids);
}
Function Rewind () {
$this->index=0;//First step to the beginning
}
Function key () {
Get Current Index
return $this->index;
}
}
$users = new AllUser ();
foreach ($users as $user)
{
Var_dump ($user);
}
Proxy mode
1. A proxy object is established between the client and the entity, and the client operations are delegated to the proxy object, hiding the entity specific implementation details.
is to write a
The basic principles of object-oriented programming
1. Single Duty: A class, only need to do a good thing
2. Open closure: A class that should be extensible and non-modifiable
3. Dependency inversion: A class that should not be strongly dependent on another class, and each class is replaceable for another class
4. Configure: Use the configuration as much as possible, not hard-coded.
5. Interface-Oriented programming: Only care about the interface, do not need to care about the implementation.
MVC Architecture Principles
Let's start with 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 that allows the array to pass values, where there are four methods to implement
protected $path;
Protected $configs =array ();
function __construct ($path)
{
$this->path= $path;
}
function Offsetget ($key) {
Gets 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
{
$file _path= $this->path. ' /'. $key. '. PHP ';//Generate Load 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)
{//Detect if the array's key exists
return Isset ($this->configs[$key]);
}
function Offsetunset ($key)
{//delete the array's key
}
}
Configuration files such as controller.php
$config = Array (
' Home ' =>array (
' Decorator ' =>array (
' Imooc\dectorator\template ',
),
),
);
Configuration and Design Patterns
Using arrayaccess in 1.PHP to implement configuration file loading
2. Read the configuration in the factory method to generate a configurable object
3. Use adorner mode for permission validation, template rendering, JSON serialization
4. A series of update operations for data update events using the Observer pattern
5. Use the proxy mode to realize the master-slave automatic switch of database
http://www.bkjia.com/PHPjc/1011354.html www.bkjia.com true http://www.bkjia.com/PHPjc/1011354.html techarticle PHP 12 Design Patterns PSR-0 Specification design basics 1. Use all namespaces 2. All PHP files must be loaded automatically and cannot have Include/require spl_autoload_register 3. Single entry mode ...