12 PHP design modes. PHP 12 design patterns PSR-0 specification Design Basics 1. all use namespaces 2. all PHP files must be loaded automatically, there cannot be javasderequirespl_autoload_register3. single entry mode PHP 12 design patterns
Design Basics of PSR-0 specifications
1. use all namespaces
2. all php files must be automatically loaded and cannot include/require
Spl_autoload_register
3. single entry mode
1. three basic design modes
Factory model
Replace a new
Class Factory {
Static function createDatabase (){
$ Db = new Database;
Return $ db;
}
}
$ Db = Factory: createDatabase ();
Singleton mode
Class Database {
Private $ db;
Private function _ construct (){
// Write the connection to the database
}
Static function getInstance (){
If (self: $ db ){
Return self: $ db;
} Else {
Self: $ db = new self ()
Return self: $ db; // private can be called by itself
}
}
Function where (){
}
}
For example
Class Factory {
Static function createDatabase (){
$ Db = Database: getInstance ();
Return $ db;
}
}
Register device (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]);
}
}
Integration with factory methods
Class Factory {
Static function createDatabase (){
$ Db = Database: getInstance ();
Register: set ('db1', $ db );
Return $ db;
}
}
Direct index call
$ Db = Register: get ('db1 ');
Adapter mode
1. the Adapter mode can encapsulate completely different function interfaces into a unified API
2. for example, PHP database operations include mysql, mysqli, and pdo. you can use the Adapter mode.
In similar scenarios, cache adapters are used to unify different cache functions, such as memcache, redis, file, and apc,
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 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; 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 ();
Rule mode
Encapsulates a group of specific behaviors and algorithms into a class to adapt to certain context. this mode is the policy mode.
The actual application distance. for example, if a website system of an e-commerce system is used to redirect male and female users to different product categories
First, declare the interface file of a policy.
Interface UserStrategy {
Function showAd ();
Function showcategory ();
}
// The first policy is for a female user.
Class femaleUserStrategy implements UserStrategy {
Function showAd (){
Echo '2014 new women's clothing ';
}
Function showCategory ()
{
Echo 'Women's clothing ';
}
}
// Second policy for male users
Class maleUserStrategy implements UserStrategy {
Function showAd (){
Echo '2014 new men's wear ';
}
Function showCategory ()
{
Echo 'Men's manual ';
}
}
// 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 hard coding to decoupling
Data Object ing mode
The data object ing mode maps objects and data storage.
Object operations are mapped to operations on data storage.
To implement the data object ing mode in the code, we will implement an ORM class to map complex SQL statements into object attributes.
Class User {
Public $ id;
Public $ name;
Public $ mobile;
Public $ regtime;
Protected $ db;
Function _ construct ($ id ){
// Retrieve 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 modified
$ 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
$ User-> mobile = '000000 ';
$ User-> name = 'test ';
$ User-> regtime = time ();
// There are no SQL statements here. only operations on objects are allowed.
Comprehensive Application (factory, register, and adapter)
And
Observer Mode
1. in The Observer mode, when the status of an object changes, all objects dependent on it will be notified and updated automatically.
2. scenario: After an event occurs, a series of update operations must be performed. in the traditional programming method
The processing logic is directly added after the event code. when the update logic increases, the code becomes difficult to maintain. this method is coupled and intrusive,
To increase the logic, you need to modify the code of the event subject.
3. the observer mode implements a low-coupling, non-intrusive notification update mechanism.
Demo
Class Event {
Function trigger (){
Echo "Event"; // indicates that the Event has occurred.
// Start writing update logic
Echo 'logical 1 ';
Echo 'logical 2 ';
Echo 'logical 3 ';
}
}
$ Event = new Event (); // The traditional method is coupling, intrusive,
// The source code must be changed, so we define an observer mode.
Demo
// Next 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 );
}
// In this case, we need the Event class to inherit the base class.
Class Event extends EventGenerator {
Function trigger (){
Echo "Event"; // indicates that the Event has occurred.
$ This-> Policy ();
}
}
Class Observer1 implements Observer {
Function updata ($ event_info = null)
{
Echo "logic 1 ";
}
}
Class Oberver2 implements Oberver {
Function updata ($ event_info = null)
{
Echo "logic 2 ";
}
}
Prototype
1. similar to the factory mode, it is used to create objects.
2. Unlike the implementation of the factory model, the prototype creates a prototype first.
Object, and then create a new object by cloning the prototype object.
Repeated initialization operations during creation
3. the prototype mode is suitable for creating large objects. creating a large object requires a great deal of overhead. if new objects are created every time,
In prototype mode, you only need to copy the memory.
Suppose there is a layout class. New is complex
I want to use him twice again
In this way, we can use the prototype mode to solve the new problem and replace new with clone.
After initialization, clone the file directly.
Decorator mode
1. the modifier mode allows you to dynamically add and modify the class function.
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 re-implement the class method.
3. in 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
Write a subclass to inherit the canvas class.
Override the canvas generation method. What if we want to add many functions?
Do you want to rewrite many classes?
Next we will solve this problem using the decorator mode.
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 it in the draw () method.
Function draw (){
$ This-> beforeDraw ();
// Here is the content of the original code
$ This-> afterDraw ();
}
Then add a protected $ decorators [] = array ();
Add a method to receive the modifier interface
Function addDecorator (DrawDecorator $ decorator ){
$ This-> decorators [] = $ decorator;
}
Add two methods to call the decorator.
Function beforeDraw (){
Foreach ($ this-> decorators as $ decorator)
{
$ Decorator-> beforeDraw ();
}
}
Function afterDraw (){
// Reverse, first-in-first-out
$ Decorators = array_reverse ($ this-> decorators );
Foreach ($ decorators as $ decorator)
{
$ Decorator-> afterDraw ();
}
}
We have a color ornament.
Class ColorDrawDecorator implements DrawDecorator {
Protected $ color;
Function _ construct ($ color = 'red ')
{
$ This-> color = $ color;
}
Function beforDraw ()
{
Echo"
";
}
Function afterDraw ()
{
Echo"
"
}
}
Here we don't need to inherit to implement it.
$ A = new canvas (); // instantiate the canvas class
$ A-> init (); // Initialization
$ A-> addDecorator (new colorDrawDecorator ('green'); // add a color modifier class
Iterator mode
1. the iterator mode traverses yige without having to know the internal implementation.
Internal elements of an aggregate object
2. compared with the traditional programming mode, the iterator mode 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 the iterator
Protected $ data = array ();
// Iterator is the Iterator interface
Fucntion _ construct (){
$ Db = Factory: getDatabase ();
$ Result = $ db-> query ("selecy id from user ");
$ This-> ids = $ db-> mysql_fetch_assoc ($ result );
}
Function current (){
// Obtain the current element
$ Id = $ this-> ids [$ this-> index] ['id'];
Return Factory: getUser ($ id );
}
Function next (){
// The next element
$ This-> index ++;
}
Function valid ()
{
// Determine whether data exists
Return $ this-> index <count ($ this-> ids );
}
Function rewind (){
$ This-> index = 0; // start from step 1
}
Function key (){
// Obtain the current index
Return $ this-> index;
}
}
$ Users = new Alluser ();
Foreach ($ users as $ user)
{
Var_dump ($ user );
}
Proxy mode
1. create a proxy between the client and the object. the client delegates all operations on the object to the proxy object to hide the specific implementation details of the object.
Is to write
Basic principles of object-oriented programming
1. single responsibility: one class, only one thing needs to be done
2. open and closed: a class should be extensible and cannot be modified.
3. Dependency Inversion: a class should not be highly dependent on another class. Each class is replaceable for another class.
4. configuration: Use the configuration as much as possible, instead of hard encoding.
5. Interface-Oriented Programming: you only need to care about the interface and do not need to care about the implementation.
MVC architecture principle
Let's first create a Config object.
$ Config = new Config (_ DIR _. '/configs ');
$ Config ['controller'];
There is a Config class.
Class Config implements \ ArrayAccess {
// The ArrayAccess interface is a built-in interface that allows values to be transmitted through arrays. four methods are required.
Protected $ path;
Protected $ configs = array ();
Function _ construct ($ path)
{
$ This-> path = $ path;
}
Function offsetGet ($ key ){
// Obtain the key of the configuration array file name
If (empty ($ this-> configs [$ key])
// If the array file name does not exist in the original configuration file, load it.
{
$ File_path = $ this-> path. '/'. $ key. '. php'; // Generate the 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 array key 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 (
'Recorator' => array (
'Imooc \ Dectorator \ template ',
),
),
);
Configuration and design mode
1. use ArrayAccess in PHP to load configuration files
2. read the configuration in the factory method to generate configurable objects.
3. permission verification, template rendering, and json string using the decorator mode
4. a series of update operations for data update events using the observer mode
5. use the proxy mode to automatically switch between master and slave databases
Drawing 12 design patterns PSR-0 specification Design Basics 1. using namespaces all 2. all php files must be loaded automatically and there cannot be include/require spl_autoload_register 3. single entry mode...