1. 将课堂代码全部上机操作至少一遍以上。
单列模式:
实例
<?php namespace _1205; use PDO; // 单列模式 class Temp { // } $obj1 = new Temp(); $obj2 = new Temp(); var_dump($obj1, $obj2); echo '<br>'; var_dump($obj1 === $obj2); echo '<hr>'; // 单列模式原理 class Demo1 { // 不让外部实例化操作,将构造方法私有化 private function __construct() { } // 目前只能在类的内部进行实例化该类 // 在不能实例化的情况下,我们只能使用类来访问,用类来访问类中成员必须是静态成员。 // 因此,需要插件两个静态成员 // 第一个静态成员,是当前类的实例 public static $instance = null; // 第二个静态成员,是实例化当前类的方法 public static function getInstance() { // 作用:实例化当前类,并且返回实例/对象 /** * 分两步 * 1.判断当前类是否被实例化过了。如果没有被实例化,就实例化该类。如果已实例化,就返回即可。 */ if (is_null(self::$instance)) { //如果没有实例化,则实例化该类并保存到$instance静态属性里 self::$instance = new self(); //$instance是静态属性,所以需要self调用 } // 如果已经实例化该类,则返回它 return self::$instance; } // 禁用克隆方法,保证该类有唯一实例。 private function __clone() { // TODO: Implement __clone() method. } } // 测试 //通过类访问静态方法getInstance(), $obj1 = Demo1::getInstance(); $obj2 = Demo1::getInstance(); echo '<br>'; var_dump($obj1 === $obj2); echo '<hr>'; // 单列模式应用场景 class Db { // 不让外部实例化操作,将构造方法私有化 // 构造方法接受参数,因为构造方法每次都默认调用,所以接收参数来实现屎壳郎连接。 private function __construct(...$connect) { //将构造方法接收的数据提取出来 $dsn = $connect[0]; $username = $connect[1]; $password = $connect[2]; //创建Pdo实例 self::$pdo = new \PDO($dsn, $username, $password); } // 目前只能在类的内部进行实例化该类 // 在不能实例化的情况下,我们只能使用类来访问,用类来访问类中成员必须是静态成员。 // 因此,需要插件两个静态成员 // 第一个静态成员,是当前类的实例 public static $pdo = null; // 第二个静态成员,是实例化当前类的方法 //接受外部传入参数 public static function getInstance(...$connect) { // 作用:实例化当前类,并且返回实例/对象 /** * 分两步 * 1.判断当前类是否被实例化过了。如果没有被实例化,就实例化该类。如果已实例化,就返回即可。 */ if (is_null(self::$pdo)) { //如果没有实例化,则实例化该类并保存到$instance静态属性里 //创建实例化时添加参数。 // 构造函数不需要返回 new self(...$connect); // } // 如果已经实例化该类,则返回它 return self::$pdo; } // 禁用克隆方法,保证该类有唯一实例。 private function __clone() { // TODO: Implement __clone() method. } } //连接数据库参数 $connect = ['mysql:host=localhost;dbname=test', 'root', 'root']; //创建连接对象 $pdo = Db::getInstance(...$connect); echo '<hr>'; $sql = $pdo->query('select * from goods'); echo '<pre>'; print_r($sql->fetchAll()); echo '<pre>';
工厂模式:
实例
<?php namespace _1205; // 工厂模式;用于批量创建类的实例或对象, class Test1 { public function __construct($arg1) { // 输出 echo '对象创建成功,参数是:' . $arg1 . '<br>'; } } class Test2 { public function __construct($arg1, $arg2) { // 输出 echo '对象创建成功,参数是:' . implode(',', [$arg1, $arg2]) . '<br>'; } } class Test3 { public function __construct($arg1, $arg2, $arg3) { // 输出 echo '对象创建成功,参数是:' . implode(',', [$arg1, $arg2, $arg3]) . '<br>'; } } // 创建工厂类,专用批量创建类实例、对象 class Factory { /** * 专用实例化类 * 参数1:类的名称 * 参数2:构造方法的参数 * @param $className * @param array $arg * @return mixed */ public static function create($className, ...$arg) { // new一个类,并且传参,需要返回 return new $className(...$arg); } } // 通工厂类来创建实例、对象 Factory::create(Test1::class, 100); Factory::create(Test2::class, 100, 50); Factory::create(Test3::class, 100, 50, 1);
依赖注入:
实例
<?php namespace _1205; // 依赖注入:解决对象调用之间的耦合 // 工作类 class Person { // 创建一个属性来保存外部的依赖对象 private $car = null; // 在构造方法中将依赖的外部对象全部实现实例化 // 将注入点放到构造方法中 public function __construct() { // 创建Car对象 $this->car = new Car(); // 依赖注入的目的,就是将类方法中new干掉 } // 调用外部对象,执行一个动作 public function work() { // 调用外部所依赖的对象, // 因为在构造方法中已经实现了依赖对象实例化,所以使用$this return $this->car->drive(); } } // 依赖的外部对象 class Car { public function drive() { return '开车'; } } // 依赖类注入到工作类进行工作 // 实例化工作类 $Person = new Person(); echo $Person->work(); echo '<hr>'; // ******************************************* // 依赖注入:解决对象调用之间的耦合 // 工作类 class Person1 { // 创建一个属性来保存外部的依赖对象 private $car = null; // 在构造方法中将依赖的外部对象全部实现实例化 // 将注入点放到构造方法中 public function __construct(Car1 $car) { // 创建Car对象 $this->car = $car; // 依赖注入的目的,就是将类方法中new干掉 } // 调用外部对象,执行一个动作 public function work() { // 调用外部所依赖的对象, // 因为在构造方法中已经实现了依赖对象实例化,所以使用$this return $this->car->drive(); } } // 依赖的外部对象 class Car1 { public function drive() { return '开车'; } } // 依赖类注入到工作类进行工作 // 实例化Car1 $car = new Car1(); // 遇到一个问题:在工作类构造方法定义的类型变量必须一致不然会找不到实例 $person = new Person1($car); echo $person->work(); echo '<hr>';
容器:
容器类
<?php // 容器类 namespace lessno; // 引入闭包别名 use Closure; class Container { // 创建数组,保存类的实例化对象,也叫类实例容器 protected $instance = []; /** *将类实例化的过程绑定到容器中 * @param [type] $alias 当前类的别名 * @param Closure $closure 执行过程 * @return void */ public function bind($alias, Closure $process) { /** * 帮获取类的实例化保存到数组中 * [$alias]数组的健名 * = $process数组的值 */ $this->instance[$alias] = $process; } // 取出保存在容器中的实例化过程的闭包,并执行它 // 参数:实例化的那个类 public function make($alias) { // 执行 return $this->instance[$alias](); } }
调用类
<?php namespace lessno; require 'Protuct.php'; require 'Maker.php'; require 'Container.php'; // 传统方式使用 class Clinet2 { // 输出 // 参数1:Protuct类的实例 // 参数2:Maker类的实例对象 public function show(Protuct $protuct, Maker $maker) { // 将制造商注入到商品类中 return $protuct->get($maker); } } // 调用 // 将类实例绑定到容器中并实例化返回 $container = new Container(); /** * 执行绑定 * 参数1:类的别名,自定义,为了阅读,建议使用类名 */ $container->bind('protuct', function () { return new Protuct(); }); $container->bind('maker', function () { return new Maker(); }); /** * 创建实例并返回 * 参数1:绑定的别名 * 参数2: */ $protuct = $container->make('protuct'); $maker = $container->make('maker'); // 创建类的实例并返回 $obj = new Clinet2(); echo $obj->show($protuct, $maker);
面向接口:
调用类
<?php // 旅行类,使用传统方式 namespace base; // 设置引用的类的别名 use base\inc2\Car; use base\inc2\Plane; use base\inc2\Train; use base\inc2\iVehicle; require __DIR__ . '/autoload.php'; class Travel3 { // 交通工具 private $vehicle; // 构造方法,传入接口 public function __construct(iVehicle $vehicle) { $this->vehicle = $vehicle; } // 调用外部依赖对象 public function travelModel() { // 调用对象 return $this->vehicle->drive() . ':3去旅行'; } } // 客户端调用 echo (new Travel3(new Car()))->travelModel() . '<br>'; echo (new Travel3(new Plane()))->travelModel() . '<br>'; echo (new Travel3(new Train()))->travelModel() . '<br>';
2. 代码中的注释文字, 不得少于代码量的四分之一。
3. 手写课堂笔记:1205.md
总结:
单列模式:构造方法私有化,添加两个静态成员来保存当前类的实例和实现该类实例化的方法。通过类名调用静态方法,实现类的唯一实例。
工厂模式:用于批量创建类的实例或对象,创建一个类,添加一个静态方法,参数1是类的名字,参数2是构造方法的参数,在方法new 参数1传参参数2,并且返回。
依赖注入:创建一个工作类,类成员有构造方法,在外部实例化依赖类,传参工作类构造方法实现依赖注入。解决对象调用之间的耦合。
容器:通过一个类来代理生成对象实例,并且执行返回,统一了实例化
使用面向接口。功能好扩展,使代码更灵活。