Summary of php design patterns
- 2020-05-30 19:41:03
- OfStack
1. Singleton mode
The singleton pattern means that at any given time, only one instance of this class exists in the application. Typically, we use the singleton pattern to allow only one object to access the database, preventing multiple database connections from being opened. To implement a singleton class, include the following:
Unlike normal classes, singletons cannot be instantiated directly, only by themselves. Therefore, to achieve such a limiting effect, the constructor must be marked private.
For a singleton class to work without being directly instantiated, it must be provided with such an instance. Therefore, it is imperative that the singleton class have a private static member variable that can hold an instance of the class and a corresponding public static method that can access the instance.
In PHP, to prevent the cloning of singleton class objects to break up the above implementation of the singleton class, an empty private method is usually provided for the base.
Here is a basic singleton pattern:
class SingetonBasic {
private static $instance;
// other vars..
private function __construct() {
// do construct..
}
private function __clone() {}
public static function getInstance() {
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
// other functions..
}
$a = SingetonBasic::getInstance();
$b = SingetonBasic::getInstance();
var_dump($a === $b);
2. Factory mode
The factory pattern allows you to create a class that specifically implements and returns instances of other classes depending on the input parameters or application configuration. Here is a basic factory model:
class FactoryBasic {
public static function create($config) {
}
}
For example, here is a factory that describes a shape object, and it wants to create different shapes according to the number of parameters it passes in.
// Define the common function of the shape: get the perimeter and area.
interface IShape {
function getCircum();
function getArea();
}
// Define the rectangle class
class Rectangle implements IShape {
private $width, $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
public function getCircum() {
return 2 * ($this->width + $this->height);
}
public function getArea() {
return $this->width * $this->height;
}
}
// Class definitions circle
class Circle implements IShape {
private $radii;
public function __construct($radii) {
$this->radii = $radii;
}
public function getCircum() {
return 2 * M_PI * $this->radii;
}
public function getArea() {
return M_PI * pow($this->radii, 2);
}
}
// Create different shapes based on the number of parameters passed in.
class FactoryShape {
public static function create() {
switch (func_num_args()) {
case 1:
return new Circle(func_get_arg(0));
break;
case 2:
return new Rectangle(func_get_arg(0), func_get_arg(1));
break;
}
}
}
// Rectangular object
$c = FactoryShape::create(4, 2);
var_dump($c->getArea());
// Round object
$o = FactoryShape::create(2);
var_dump($o->getArea());
Using the factory pattern makes it easier to call a method because it has only one class and one method, and if the factory pattern is not used, you have to decide which class and which method should be called at the time of invocation. Using the factory pattern also makes it easier to make changes to the application in the future, such as adding support for a shape by modifying only one of the create() methods in the factory class, rather than modifying the code block that calls the shape without using the factory pattern.
3. Observer mode
The observer pattern gives you another way to avoid tight coupling between components. The pattern is simple: one object makes itself observable by adding a method that allows another object, the observer, to register itself. When an observable object changes, it sends a message to a registered observer. These observers use this information to perform operations independent of the observable object. The result is that objects can talk to each other without knowing the cause.
A simple example: when a listener is listening to a radio station (that is, a radio station joins a new listener), it will send a prompt message that can be observed by the log observer sending the message.
// Observer interface
interface IObserver {
function onListen($sender, $args);
function getName();
}
// Can be observed interface
interface IObservable {
function addObserver($observer);
function removeObserver($observer_name);
}
// Observer class
abstract class Observer implements IObserver {
protected $name;
public function getName() {
return $this->name;
}
}
// Observable class
class Observable implements IObservable {
protected $observers = array();
public function addObserver($observer) {
if (!($observer instanceof IObserver)) {
return;
}
$this->observers[] = $observer;
}
public function removeObserver($observer_name) {
foreach ($this->observers as $index => $observer) {
if ($observer->getName() === $observer_name) {
array_splice($this->observers, $index, 1);
return;
}
}
}
}
// simulation 1 Classes that can be observed: RadioStation
class RadioStation extends Observable {
public function addListener($listener) {
foreach ($this->observers as $observer) {
$observer->onListen($this, $listener);
}
}
}
// simulation 1 Individual observer class
class RadioStationLogger extends Observer {
protected $name = 'logger';
public function onListen($sender, $args) {
echo $args, ' join the radiostation.<br/>';
}
}
// Simulation and 1 Individual observer class
class OtherObserver extends Observer {
protected $name = 'other';
public function onListen($sender, $args) {
echo 'other observer..<br/>';
}
}
$rs = new RadioStation();
// Injection observer
$rs->addObserver(new RadioStationLogger());
$rs->addObserver(new OtherObserver());
// Remove observer
$rs->removeObserver('other');
// You can see the observed information
$rs->addListener('cctv');