PHP_Design Patterns

Posted by sp@rky13 on Thu, 27 Jun 2019 23:03:00 +0200

What is design pattern?

Typical solutions to classical scenarios that often occur in software development are called design patterns.

How to Learn Design Patterns

Typical scenarios - > Typical problems - > Typical solutions

polymorphic

Used to eliminate logical statements.

Polymorphism (ploymorphism) is a biological concept, referring to the multiple manifestations of the same species.

In object-oriented, it refers to the different forms of an object instance.

<?php

abstract class Tiger {
  public abstract function climb();
}

class XTiger extends Tiger {
  public function climb() {
    echo 'Drop' , '<br/>';
  }
}

class MTiger extends Tiger {
  public function climb() {
    echo 'Up' , '<br/>';
  }
}

class Cat {
  public function climb() {
    echo 'Fly';
  }
}

class Client {
  public static function call(Tiger $animal) { // The parameter restriction is not strict, it can be more flexible, it can pass a parent type, it can have different subclass morphology.
    $animal->climb();
  }
}

Client::call(new XTiger());
Client::call(new MTiger());
Client::call(new Cat());

?>

Of the 23 design patterns, some can be eliminated naturally.

Interface-Oriented Development

Reduce the operation of new.

Familiar with concepts:

The concept of caller side
The Concept of Client

For example, in Java, you write a bunch of classes and end up with a package. The caller can introduce the package and then use the methods defined in the class to view the methods in the development process.

Hypothesis: sdk is introduced into development, which is not to be seen. How to invoke, we must open some interfaces. Existence of Interface-oriented development

Interfaces: Common Rules

Interface-Oriented Development

<?php


// Common interface
// Server Packing
interface DB {
  function conn();
}


// Server-side development (I don't know who will call it)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


// *** Client **** ** (you can't see the internal implementation details of DbMysql,DbSqlite)
// All you know is that these two classes implement the db interface

$db = new DbMysql();
$db->conn();

$db = new DbSqlite();
$db->conn();

// Both the developer and the caller are responsible for the interface

Simple factory model

The role of the model:
The less you know, the better.

In object-oriented design, the important open-close principle is that it is closed for modification and open for extension.

<?php


// Common interface
// Server Packing
interface DB {
  function conn();
}


// Server-side development (I don't know who will call it)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


// Simple Factory
class Factory {
  public static function createDB($type) {
    if ($type == 'mysql') {
      return new DbMysql();
    } else if ($type == 'sqlite') {
      return new DbSqlite();
    } else {
      throw new Exception('Error db type', 1);
    }
  }
}


// The client does not know what class names the server has.
// Only know that the other party has opened a Factory::createDB method.
// Static methods allow passing database names

$msqyl = Factory::createDB('mysql');
$msqyl->conn();

$sqlit  = Factory::createDB('sqlite');
$sqlit->conn();


// What if the oracle type is added?
// The server needs to modify the Factory content (in Java, C++, it has to be compiled after the modification)
// In object-oriented design principles, the important open-close principle is that it is closed for modification and open for extension.

// Requirements can be implemented by extending subclasses.

Factory Method

Extension to avoid modification of the original data, only need to add new code subclasses, can be completed.

It is closed for modification and open for extension.

<?php


// Common interface
// Interface of database
interface DB {
  function conn();
}

// Creating database interfaces
interface Factory {
  function createDB();
}

// Server-side development (I don't know who will call it)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


class MySqlFactory implements Factory {
  public function createDB() {
    return new DbMysql();
  }
}

class SqliteFactory implements Factory {
  public function createDB() {
    return new DbSqlite();
  }
}



// ==== Adding oracle classes on the server side
// Extension to avoid modification of original data
class orcale implements DB {
  public function conn() {
    echo 'conn orcal <br />';
  }
}

class orcaleFactory implements Factory {
  public function createDB() {
    return new orcale();
  }
}


// The client starts calling.

$fact = new MysqlFactory();
$db = $fact->createDB();
$db->conn();


$fact = new SqliteFactory();
$db = $fact->createDB();
$db->conn();

Singleton pattern

Common usage scenarios:

  1. When database classes are needed

  2. Operating cookie classes

  3. Upload Picture Class

DB.class.php
Upload.class.php
Cookie.class.php
// All three classes need to read the configuration file information, and the configuration file is common, so it is enough that the configuration reading class has an object. 
// (How to ensure that there is only one object)

When are PHP objects all-equal

Two objects are one time.

Singleton pattern implementation

  1. Closed external new operation

  2. Open a common interface inside, take charge of new operation, control a single instance

  3. Inheritance override _construcotr is prohibited

  4. Preventing cloning

<?php

/**
  Singleton pattern
*/

// First step, general class

// class Single {

// }


// $s1 = new Single();
// $s2 = new Single();

// var_dump($s1, $s2);
// var_dump($s1 == $s2);

// ---------------------

// The second step is to block the new operation
// class Single {
//   // The magic function is triggered when new, _constructor, which can be manipulated in the _constructor magic function. 
//   Protected function constructor() {// Protects constructor() magic method, resulting in the consequence that no object can be new. (The door is closed and the window needs to be opened)

//   }
// }

// $s1 = new Single();


// ---------------------

// The third step is to leave the interface to the new object
// class Single {
//    Public static function getIns () {// getIns has control inside the class and can be manipulated in getIns.
//      return new self(); // return its own instance
//    } 
//    protected function __constructor() {

//    }
// }

// $s1 = Single::getIns();
// $s2 = Single::getIns();

// var_dump($s1, $s2);
// var_dump($s1 == $s2);



// ---------------------

// Step 4, getIns prejudges instances
// class Single {
//    protected static $ins = null;
//    Public static function getIns () {// getIns has control inside the class and can be manipulated in getIns.
//      if (self::$ins === null) {
//        self::$ins = new self();
//      }
//      return self::$ins; // return its own instance
//    } 
//    protected function __constructor() {

//    }
// }

// $s1 = Single::getIns();
// $s2 = Single::getIns();

// var_dump($s1, $s2);
// var_dump($s1 == $s2); // true

// Question: After inheritance, the constructor is exposed, and you can use final
// class multi extends Single {
//   Public function _constructor() {// After inheritance, the constructor is exposed

//   }
// } 




// ---------------------

// The fifth step, final, prevents the right to be modified when inheriting
// class Single {
//    protected static $ins = null;
//    Public static function getIns () {// getIns has control inside the class and can be manipulated in getIns.
//      if (self::$ins === null) {
//        self::$ins = new self();
//      }
//      return self::$ins; // return its own instance
//    } 
//    The final protected function _constructor() {// method preceded by final, then the method can not be overwritten, and the class can not be inherited by adding final before the class.

//    }
// }

// class multi extends Single {
//   Public function _constructor() {// After inheritance, the constructor is exposed

//   }
// } 

// $s1 = Single::getIns();
// $s2 = clone $s1; // cloned, and multiple objects were generated.

// var_dump($s1, $s2);
// var_dump($s1 === $s2); // true




// ---------------------

// Step 6. Ban clone
class Single {
   protected static $ins = null;
   public static function getIns() { // The control of getIns is within the class and can be manipulated by getIns.
     if (self::$ins === null) {
       self::$ins = new self();
     }
     return self::$ins;  // Return to your own instance
   } 
   final protected function __constructor() { // If the method is preceded by final, the method cannot be overwritten, and if the class is preceded by final, the class cannot be inherited.

   }

   // clone blockade
   final protected function __clone() {

   }
}

$s1 = Single::getIns();
$s2 = clone $s1; // Cloned, and produced multiple objects.

var_dump($s1, $s2);
var_dump($s1 === $s2); // true

Topics: PHP MySQL SQLite Database