2
头图

🎈 Factory Mode

  • The principle of the factory pattern
  • Function: that is, as long as you pass the class you need in, you can get its instantiated object
  • In fact, the factory is to help you instantiate the classes you need
 <?php
/**
* 工厂类
*/
class factory
{
    public static function create($className) {
        return new $className();
    }
}
 
class A {}
class B {}
 
$a = factory::create('A');
$b = factory::create('B');
 
var_dump($a); // object(A)#1 (0) {}
var_dump($b); // object(B)#2 (0) {}
  • Application of factory pattern
  • Use when instantiating multiple classes to handle different businesses, here is the case of finding the perimeter and area of rectangles and circles
 <?php
/**
 * Interface shape
 */
interface shape
{
    public function area();
    public function perimeter();
}
 
/**
 * 矩形
 * Class rectangle
 */
class rectangle implements shape
{
    private $width;
    private $height;
 
    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }
 
    public function area() {
        return $this->width * $this->height;
    }
 
    public function perimeter() {
        return 2 * ($this->width + $this->height);
    }
}
 
/**
 * 圆
 * Class circle
 */
class circle implements shape
{
    private $radius;
 
    public function __construct($radius) {
        $this->radius = $radius;
    }
 
    public function area() {
        return M_PI * pow($this->radius, 2);
    }
 
    public function perimeter() {
        return 2 * M_PI * $this->radius;
    }
}
 
/**
 * 工厂类
 * Class factory
 */
class factory
{
    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;
        }
    }
}
 
$a = factory::create(4, 5);
$b = factory::create(2);
 
echo '矩形的周长为:' . $a->perimeter();
echo '矩形的面积为:' . $a->area();
echo '圆的周长为:' . $a->perimeter();
echo '圆的面积为:' . $a->area();

🎈 Singleton pattern

  • The principle of the singleton pattern
  • Function: When you instantiate a class multiple times, let it only exist in a unique memory space to reduce resource consumption
  • The instantiation of a common class, one new will create an instantiated memory space, because the space is different, this will increase the system memory overhead
  • But the same class has the same function, there is no need to put it in different memory spaces
 <?php
/**
 * Class A
 */
class A {}
 
$a = new A();
$b = new A();

// 非单例模式中可以看到其中#1,#2分属不同的内存空间
var_dump($a); // object(A)#1 (0) {}
var_dump($b); // object(A)#2 (0) {}
  • Definition of Singleton Pattern
  • The entry formula for the singleton pattern is: three private and one public
  • Private construction method: prevent artificial external use new to create this is the instantiation of the above common
  • Private clone method: prevent artificial external use clone method after instantiation
  • Private static properties: used to store a single instantiated object
  • Public static method: used to implement a single instantiation logic
  • From the results: the object memory space of both classes points to #1 , which realizes the basic construction of the singleton pattern
 <?php
/**
 * Class database
 */
class database
{
    /**
     * @var $instance
     */
    private static $instance;
 
    /**
     * 私有的构造方法,禁止外部实例化
     * database constructor.
     */
    private function __construct() {}
 
    /**
     * 私有的克隆方法,禁止外部克隆
     */
    private function __clone() {}
 
    /**
     * 获取单例
     * @return database
     */
    public static function getInstance()
    {
        if(!self::$instance instanceof self) {
            self::$instance = new self();
        }
 
        return self::$instance;
    }
}
 
$a = database::getInstance();
$b = database::getInstance();

var_dump($a); // object(database)#1 (0) {}
var_dump($b); // object(database)#1 (0) {}
  • Application of the singleton pattern
  • In fact, there are many applications of the singleton pattern in the project. It is nothing more than that some things only need to instantiate an object, and there is no need to instantiate multiple times.
  • The common application scenarios include PDO connection to database, Redis connection, etc.
 <?php
/**
 * Class mysql
 */
class mysql
{
    /**
     * @var \PDO
     */
    private $pdo;
 
    /**
     * @var $instance
     */
    private static $instance;
 
    /**
     * @var array
     */
    private $_config = [
        'host' => '127.0.0.1',
        'post' => 3306,
        'user' => 'root',
        'password' => '',
        'charset' => 'utf8',
        'dbname' => 'autofelix',
        'except' => 'PDO::ERRMODE_EXCEPTION'
    ];
 
    /**
     * mysql constructor.
     */
    private function __construct() {}
 
    /**
     * 数据库链接
     */
    public function connect()
    {
        try {
            $dsn = "mysql:host={$this->_config['host']};port={$this->_config['post']};dbname={$this->_config['dbname']};charset={$this->_config['charset']}";
            $this->pdo = new PDO($dsn, $this->_config['user'], $this->_config['password']);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, $this->_config['except']);
        } catch (PDOException $e) {
            exit('数据库连接失败:' . $e->getMessage());
        }
    }
 
    /**
     * @param $sql
     * @return array
     */
    public function getAll($sql)
    {
        $this->sql = $sql;
        $pdostatement = $this->pdo->query($sql);
        return $pdostatement->fetchAll(PDO::FETCH_ASSOC);
    }
 
    /**
     * @return mysql
     */
    public static function getInstance()
    {
        if(!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }
 
    private function __clone() {}
}
 
$mysql = mysql::getInstance();
$mysql->connect();
 
$sql = 'select * from autofelix_users where 1';
$result = $mysql->getAll($sql);
echo json_encode($result);

🎈 Strategy Mode

  • Principles of the Strategy Pattern
  • Function: For example, if you go shopping on Taobao, if you are a boy, its homepage will recommend items that boys like. If you are a girl, it will recommend items commonly used by girls. The strategy mode is actually 对象进行分类
  • As can be seen from the above, the strategy mode in programming is to know who you are, and then recommend to you what you like to maximize marketing
  • It must be involved here. When the program is running, it classifies you as a person, and then executes different methods.
  • Here we define two classes with the same method but different execution content
  • What the strategy pattern needs to do is when the user comes in, the same entry allows him to execute a method in one of the classes according to the person's behavior
 <?php
/**
 * Class A
 */
class A {
    public function name()
    {
        echo "我是A类";
    }
}
 
/**
 * Class B
 */
class B {
    public function name()
    {
        echo "我是B类";
    }
}
 
/**
 * Class strategy
 */
class strategy
{
    /**
     * @var $obj
     */
    private $obj;
 
    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->obj->name();
    }
 
    /**
     * @param $class
     */
    public function setClass($class)
    {
        $this->obj = $class;
    }
}
 
$strategy = new strategy();
// 分门别类
// $strategy->setClass(new A());
$strategy->setClass(new B());
// 同一个入口
$strategy->getName(); // 我是B类
  • Application of strategy pattern
  • Scenario: For example, a user goes to a hotel website to book accommodation. Based on your historical consumption records, the page will show you high-level accommodation and rich dinners, or just general accommodation and cheap buffets.
  • We first define the interface to implement the methods of housing and dinner
  • Then define two classes in the group to implement this interface, namely the distinguished crowd and the ordinary crowd
  • When there is a autofelix user to book a room, inject the class of mass users into him
 <?php
/**
 * 定义接口
 * Interface userStrategy
 */
interface userStrategy
{
    public function hotel();
    public function dinner();
}
 
/**
 * 尊贵的客人享有的待遇
 * Class rich
 */
class rich implements userStrategy
{
    public function hotel()
    {
        return "你是高贵的客人,为你推荐了高级住宿";
    }
 
    public function dinner()
    {
        return "你是高贵的客人,为你推荐了烛光晚餐";
    }
}
 
/**
 * 普通的客人享有的待遇
 * Class poor
 */
class poor implements userStrategy
{
    public function hotel()
    {
        return "你是普通的客人,为你推荐了大众住宿";
    }
 
    public function dinner()
    {
        return "你是普通的客人,为你推荐了自助餐";
    }
}
 
/**
 * Class user
 */
class user
{
    private $_userClass;
 
    public function getHotel() {
        return $this->_userClass->hotel();
    }
 
    public function getDinner() {
        return $this->_userClass->dinner();
    }
 
    public function setUserClass(userStrategy $userStrategy) {
        $this->_userClass = $userStrategy;
    }
}
 
/**
 * 这时候有个autofelix用户过来网站预定房间
 * Class autofelix
 */
class autofelix extends user {}
 
$people = new autofelix();
 
//设置群体
$people->setUserClass(new poor());
 
//获取该群体的住宿和晚餐
$hotel = $people->getHotel();
$dinner = $people->getDinner();
 
echo json_encode([
    'hotel' => $hotel,
    'dinner' => $dinner
]);

// 结果如下
{
    hotel: "你是普通的客人,为你推荐了大众住宿",
    dinner: "你是普通的客人,为你推荐了自助餐"
}

🎈 Adapter Mode

  • The principle of the adapter pattern
  • Function: Convert the interface of a class into another interface that the client wants. The adapter mode makes the original classes that cannot work together due to incompatible interfaces work together.
  • For example: in a certain scenario, the old project wrote a lot of interfaces that you call, but suddenly one day, the boss said that you need to change the interface method name to call, you need to use another method name to achieve the same function
  • Did you directly change the method name of the backend code? This is definitely not going to work, because the project is not the only place where you call this interface. Once you modify it, other places will collapse. You should re-copy the logic code and change the name. span
 <?php
 
class A
{
    private $str;
 
    public function __construct($str)
    {
        $this->str = $str;
    }
 
    public function getStr()
    {
        return $this->str;
    }
 
    // 错误示范,直接复制 getStr 中的代码改个方法名,臃肿
    public function getString()
    {
        return $this->str;
    }
}
 
//适配器模式前
$a = new A('i am autofelix');
$result = $a->getStr();
var_dump($result);
  • Application of Adapter Mode
  • The correct common, should be to use the adapter mode to deal with such problems
  • By defining a unified interface, and then by implementing the interface to achieve
 <?php
// 项目原本代码
class A
{
    private $str;
 
    public function __construct($str)
    {
        $this->str = $str;
    }
 
    public function getStr()
    {
        return $this->str;
    }
}

// 定义统一接口
interface AInterface {
    function getString();
}
 
class B implements AInterface
{
    /**
     * @var A
     */
    private $_A;
 
    public function __construct($class)
    {
        $this->_A = $class;
    }
 
    public function getString()
    {
        return $this->_A->getStr();
    }
}
 
// 适配器模式前
$a = new A('i am autofelix');
$result = $a->getStr();
var_dump($result);

// 适配器模式后
$b = new B($a);
$result = $b->getString();
var_dump($result);

🎈 Observer Mode

  • The principle of the observer pattern
  • Function: used to monitor some operations of the user, and then process some follow-up things according to these operations of the user
  • For example: a user buys a movie ticket online. After the payment is successful, the system needs to send a text message to the user, and record the log of the user's ticket purchase and other logical operations.
 // 系统自带的观察者接口
// 默认需要实现 onListen 和 getObserverName 这两个方法
// 如果是自定义观察者接口名,一定要实现onListen同功能的方法
// onListen 注册监听行为
interface InterfaceObserver
{
    public function onListen($sender, $args);
    public function getObserverName();
}

// 定义可被观察者的接口
// 其实就是用来监听事件的发生
// addObserver 方法我们是用来依赖注入一些用户购票之后系统的行为操作
// removeObserver 方法,是用来移除某个后续操作的,我们暂时不去实现
interface InterfaceObservable
{
    public function addObserver($observer);
    public function removeObserver($observer_name);
}
  • Application of the Observer Pattern
  • Here, the user needs to send information to the user and record the ticket purchase log after purchasing the ticket
 <?php
/**
 * Interface InterfaceObserver
 * 观察者接口
 */
interface InterfaceObserver
{
    public function onListen($sender, $args);
    public function getObserverName();
}
 
/**
 * Interface InterfaceObservable
 * 被观察对象接口
 */
interface InterfaceObservable
{
    public function addObserver($observer);
    public function removeObserver($observer_name);
}
 
class Ticket implements InterfaceObservable
{
    /**
     * @var array
     */
    private $_observers = [];
 
    /**
     * @param $observer
     */
    public function addObserver($observer)
    {
        if ($observer instanceof InterfaceObserver) {
            $this->_observers[] = $observer;
        }
    }
 
    /**
     * @param $observer_name
     */
    public function removeObserver($observer_name) {}
 
    /**
     * 用户购票行为
     */
    public function buy()
    {
        //用户购票逻辑,这里不详细说明,仅仅以参数代之
        $result = [
            'code' => 200,
            'msg' => '用户购票成功',
            'sign' => 'ea5070bec29826cc0f8e0b7b6861fd75'
        ];
 
        //购票成功,开始后期处理
        if($result['code'] == 200) {
            foreach ($this->_observers as $observer) {
                $observer->onListen($this, $result['sign']);
            }
        }
    }
}
 
 
/**
 * 记录用户购票日志
 * Class TicketRecord
 */
class ticketRecord implements InterfaceObserver
{
    public function onListen($sender, $args)
    {
        echo "记录用户购票成功,编号为:{$args}<br/>";
    }
 
    public function getObserverName() {}
}
 
/**
 * 给用户发送观影短信
 * Class sendMsg
 */
class sendMsg implements InterfaceObserver
{
    public function onListen($sender, $args)
    {
        echo "您的电影票购买成功,请凭编号:{$args}观影<br/>";
    }
 
    public function getObserverName() {}
}
 
$ticket = new Ticket();
$ticket->addObserver(new ticketRecord());
$ticket->addObserver(new sendMsg());
$ticket->buy();

极客飞兔
1.2k 声望649 粉丝