单例对象
// 单例模式管理class Demo1{ //构造方法私有化 private function __construct() { } // 目前只能在类中的内部将类实例化 public static $instance = null; public static function getInstance(){ // 实例化当前类,并返回实例/对象 // 判断当前类是否已经被实例化了,如果没有就实例化,如果有就返回这个实例 if (is_null(self::$instance)){ self::$instance = new self(); } return self::$instance; } // 禁用克隆魔术方法,防止类被复制,产生多个实例 private function __clone() { // ... }}// new Demo1(); 因为构造方法私有化,不能从外部访问,所以无法用new来创建Demo1实例$demo1_obj1 = Demo1::getInstance();$demo1_obj2 = Demo1::getInstance();echo var_dump($demo1_obj1 === $demo1_obj2); // 两个实例完全相等echo '<br>';var_dump($demo1_obj1,$demo1_obj2); // 两个实例ID相同echo '<hr>';// 单例模型应用场景class Db{ // 构造方法私有化 private function __construct($contentParams) { $dsn = $contentParams[0]; $user = $contentParams[1]; $password = $contentParams[2]; print_r($contentParams); echo '<hr>'; self::$pdo = new \PDO($dsn, $user, $password); } public static $pdo = null; // 实例化当前类的方法 public static function getInstance(...$contentParams) { // 实例化当前类,并返回实例/对象 // 判断当前类是否已经被实例化了,如果没有就实例化,如果有就返回这个实例 if (is_null(self::$pdo)){ new self($contentParams); } return self::$pdo; } // 禁用克隆魔术方法,防止类被复制,产生多个实例 private function __clone() { // ... }}$pdo = Db::getInstance('mysql:host=localhost;dbname=phpcn','root','123456');print_r($pdo->query('SELECT * FROM `wuxia`')->fetchAll());
工厂模式
namespace _Factory;class F1{ public function __construct($arg1) { echo '创建对象成功,参数是:' . $arg1; }}class F2{ public function __construct($arg1,$arg2) { echo '创建对象成功,参数是:' . $arg1 . $arg2; }}class F3{ public function __construct($arg1,$arg2,$arg3) { echo '创建对象成功,参数是:' . $arg1 . $arg2 . $arg3; }}class Factory{ // 静态方法接收类名与构造函数的参数 public static function creat($className, ...$arguments){ return new $className(...$arguments); }}//F1::class声明完整的类名,带有命名空间路径,不加::class找不到命名空间中的类,如果是全局类,要在类名前添加\转义,不用添加::classFactory::creat(F1::class,100);//echo F1::class; 含有完整路径的类名echo '<hr>';Factory::creat(F2::class,100,111);echo '<hr>';Factory::creat(F3::class,100,111,111);
MVC容器
class Client1{ public function show($product,$maker){ return $product->get($maker); }}//生成容器实例类$container = new Container();$container -> bind('product',function(){return new Product;});$container -> bind('maker',function(){return new Maker;});$product = $container -> make('product');$maker = $container -> make('maker');echo (new Client1())->show($product,$maker);
面向接口编程
namespace base;require __DIR__ . '/autoload.php';use base\inc2\Car;use base\inc2\Ship;use base\inc2\Plane;use base\inc2\Train;use base\inc2\iVehicle;class Travel3{ private $vehicle; public function __construct(iVehicle $vehicle) // 声明接口,只要实现了接口方法的类都可以被调用 { $this->vehicle = $vehicle; } public function travelMode(){ return $this->vehicle->drive() . ':===去旅行'; }}echo (new Travel3(new Car()))->travelMode().'<br>';echo (new Travel3(new Train()))->travelMode().'<br>';echo (new Travel3(new Plane()))->travelMode().'<br>';echo (new Travel3(new Ship()))->travelMode().'<br>';
总结
单例模式避免了对象被重复生成,适用于仅生成一次对象,类似与PDO连接,方法是首先将类中的构造函数私有化,不能通过外部访问,然后再禁用克隆模式,避免对象被重复生成,使用静态方法生成对象,在调用该方法时,判断该类是否被实例化,如果有,返回该类的实例,如果没有,创建该类的实例。
工厂模式可以一次生成多个对象实例。
面向接口编程,便于扩展,还可以避免代码耦合,在类的构造中声明接口类型,只要是实现接口的函数都可以被接收和调用。
在容器类中,我尝试了在创建类实例
make
方法中输入类的构造参数,需要在绑定bind
方法的匿名函数中写接收,然后分别在类和类构造方法中使用变量接收,最终才会生成构造类实例。