Details of common design patterns for PHP
Singleton mode:
php Exchange group: 159789818
Attribute: A singleton class can only have one instance
- Intra-class u construct constructor privatization to prevent new instances
- Intra-class u clone privatization to prevent objects from being copied
- Set a $instance private static property to save an instance of the current class
- Set a getInstance public method to get an instance of the current class
- Reduce new object operations and use memory wisely
Usually used to get a global configuration item or a class such as a database connection, operation, etc.
Demo:
1 <?php 2 Class Demo{ 3 //Save an instance of the current class 4 private static $instance; 5 //Privatization of constructors to prevent direct new Current Object 6 private function __construct(){} 7 //Destructor privatization to prevent direct external replication of the current object 8 private function __clone(){} 9 //getInstance A public function is used to get an instance of the current class 10 public static function getInstance() 11 { 12 //Determine the current class member variable instance Is it empty 13 //If not empty, return an instance of the class directly 14 //If empty, a new instance of the current class is saved to the class member variable 15 //instance, and then directly return the member variable 16 if(empty(self::$instance)) 17 { 18 //Save instance to instance In member variables 19 self::$instance = new static(); 20 //Return member variables directly 21 return self::$instance; 22 }else{ 23 //Return class instance directly 24 return self::$instance; 25 } 26 } 27 } 28 $demo1 = Demo::getInstance();//Get Instances 29 $demo2 = new Demo();//Report errors
Factory Design Pattern
Characteristic:
- Decrease system coupling
- Follow the development-closure principle to be closed to modifications and open to extensions
- Create instances of classes from factories instead of directly manipulating the new keyword to create instances of classes
- There is no need to change it everywhere, just in the class factory class.
- For example, Alipay Weixin Bank can write a factory mode to dock
Abstract Factory Demo:
<?php //PaymentFactory.php interface PaymentFactory { //Request Collection Code public function QRcode(); //Monitor receipts public function Listen(); } interface createPay { //Abstracting object creation into an interface function createOpen($class,$data);//Inward Creation function createIntro($class,$data);//Outgoing Creation } //WeChat Payment Class Class WxPay implements PayMentFactory { public function QRcode() { //WeChat Business Logic Code //Return payment code and order related parameters return "I'm WeChat QR Code"; } public function Listen() { //WeChat Business Logic Code //Return order results return "Is listening"; } } //Ali Payment Class Class aliyun implements PayMentFactory { public function QRcode() { //Business logic code //Return payment code and order related parameters return "I'm Alipay QR Code"; } public function Listen() { //Business logic code //Return order results return "Is listening"; } } //Realization createPay Interface class CreateP implements createPay { public function createOpen($class,$data =[]) { return new $class($data); } public function createIntro($class,$data = []) { return new $class($data); } } //Developer class class Client{ static function Get($class,$data = []) { $fac = new CreateP(); // var_dump($fac); return $fac->createOpen($class,$data); } } $pay = Client::Get("WxPay"); echo $pay->QRcode(); //Output, I'm WeChat QR Code
Register Mode
Characteristic:
- Solve global sharing and exchange objects
- Created object, suspended to a global array
- Go directly to the array to get it when needed
- Register object instances on the global tree
Demo:
<?php //Global Register Class Class Register { //Instances of storage classes public static $maps; //Registration operation public static function Set($name,$cla) { //Determine if stored if(array_key_exists($name,self::$maps)) { //If Global maps If already in, return directly return true; }else{ //Without name Then the instance and name Key value pairs are stored in member variables self::$maps[$name] = $cla; return true; } } //Get Class Instances public static function Get($name) { //judge name Is the value present if(array_key_exists($name,self::$maps)) { //Returns an instance of the corresponding class directly if it exists return self::$maps[$name]; }else{ //If it does not exist,Then return false Or other return false; } } }
Adapter mode adapter:
Characteristic:
- Encapsulating various function interfaces into a unified api
- Lower calls due to differences in the underlying code of the interface? (Personal understanding)
Demo (directly copied from the Internet):
Interface IDatabase <?php namespace IMooc; interface IDatabase { function connect($host, $user, $passwd, $dbname); function query($sql); function close(); } MySQL <?php namespace 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 <?php namespace IMooc\Database; use IMooc\IDatabase; class MySQLi implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysqli_connect($host, $user, $passwd, $dbname); $this->conn = $conn; } function query($sql) { return mysqli_query($this->conn, $sql); } function close() { mysqli_close($this->conn); } } PDO <?php namespace IMooc\Database; use IMooc\IDatabase; class PDO implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd); $this->conn = $conn; } function query($sql) { return $this->conn->query($sql); } function close() { unset($this->conn); } }
In the above case, PHP interacts with MySQL's database in three sets of APIs. Different APIs may be used in different scenarios. If you develop code and change the environment, you may need to change its database API. Then you need to rewrite all the code. After using the adapter mode, you can use a unified API to mask the environment changes caused by the underlying API differences.Issues to rewrite code
Observer mode
Characteristic:
- Observer mode, when an object's state changes, all objects that depend on it are notified and updated automatically
- After an event occurs, a series of updates are performed.The traditional programming idea is to add processing logic directly after the code of this event.As the logic for updates increases, the code becomes difficult to maintain.This is coupled, intrusive, and adding new logic requires modifying the event's body code.
- Observer mode implements a low-coupling, non-intrusive notification and update mechanism
Demo:
<?php //EventGenerator //Event Trigger Abstract Class abstract class EvemtGenerator { //Store Observer Class private $observer =[]; //Add an observer action public function AddOb(Observer $observer) { $this->observer[] = $observer; } //Observer Notification Operation public function notify() { //Loop class member variables and execute corresponding observer update methods foreach ($this->observer as $observer) { //Perform updates within each observer class $observer->update(); } } } //Define an observer interface interface Observer { public function update(); } //Implement an Observed Class Class Test extends EvemtGenerator { //Implement a login method public function login() { return "Landing Success"; } } //Implement an observer Class Observer1 implements Observer { //Define a logical update operation such as:Added csrf Verification public function update() { if($_POST['csrf'] == getCsrf()) { return true; }else{ exit("csrf Verification incorrect"); } } } //instantiation Test Class Observed $event = new Test(); $event->AddOb(new Observer1()); $event->login(); //Update Notification Action $event->notify();
Policy Mode:
Characteristic:
- Encapsulate a specific set of behaviors and algorithms into classes to accommodate specific contexts
- Convenient system maintenance, such as displaying different pages for each user when they log on
- decoupling
Demo:
//Define policy interfaces to standardize policy behavior interface UserStrategy { public function show(); public function message(); } //Define a user class that likes to buy suits Class SuitUser implements UserStrategy { public function show() { //Jump to suit page for user return "Jump to suit page"; } public function message() { //Send out message echo "About to show you the latest suit Somewhere"; } } //Define a user class that likes to buy Skirts Class skirtUser implements UserStrategy { public function show() { //Jump to suit page for user return "Jump to skirt recommendation page"; } public function message() { //Send out message echo "Show you the latest skirt Somewhere"; } } //Define a business class Class Users { //Store corresponding user classes private $userCla; //Execution Policy Interface public function Start() { echo "The jump page is:".$this->strategy->show(); echo "The message is:".$this->strategy->message(); } //Register the corresponding user class public function SetStrategy(UserStrategy $strategy) { $this->$userCla = $strategy; } } //Business logic code to judge user habits $user1 = "Suit"; $user2 = "skirt"; $userL = new Users(); //If the user habits are like to see or buy suits if ($user1 == "Suit"){ $userL->SetStrategy(new SuitUser()); $userL->Start(); }