批改状态:合格
老师批语:双休日 的作业, 是否写完了?
创建类的唯一实例
<?php//定义命名空间namespace _1205;// 引入PDO类别名use PDO;class Temp{}$obj1 = new Temp();$obj2 = new Temp();// 打印数据类型和值var_dump($obj1, $obj2);echo '<br>';// 判断类实例化的两个对象是否完全相等var_dump($obj1 === $obj2); // falseecho '<hr>';// 单例模式:创建类的唯一实例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(); // 报错,在外部无法创建类对象/实例// 只能通过类名来进行实例化$obj1 = Demo1::getInstance();$obj2 = Demo1::getInstance();var_dump($obj1 === $obj2); // trueecho '<br>';var_dump($obj1, $obj2);echo '<hr>';// 单例模式应用场景class Db{// 目前,只能在类内部将类实例化// 当前类的实例public static $pdo = null;// 构造方法私有化// 用剩余参数可以使参数以数组传入private function __construct(...$connectParams){$dsn = $connectParams[0];$username = $connectParams[1];$password = $connectParams[2];self::$pdo = new PDO($dsn, $username, $password);}// 实例化当前类的方法public static function getInstance(...$connectParams){// 实例化当前类,并返回类实例/对象// 首先判断当前类是否已经被实例化过了,如果没有的话就实例化,如果已实例化,就返回它if (is_null(self::$pdo)) {// 由于在构造方法中$pdo已经初始化了,所以不需要再对$pdo赋值了new self(...$connectParams);}return self::$pdo;}// 禁用克隆魔术方法private function __clone(){}}$connectParams = ['mysql:host=localhost;dbname=test','root','root'];$pdo = Db::getInstance(...$connectParams);// 通过PDO::query 执行SQL语句,返回结果集echo '<pre>' . print_r($pdo->query('SELECT * FROM `computer`')->fetchAll(),true) . '</pre>';

批量创建类实例/对象
<?php// 定义命名空间namespace _1205;// 工厂模式:用于批量创建类的实例/对象class Demo2{}// 举例:在三个文件中,创建类实例// file1.php$obj = new Demo2();// file2.php$obj = new Demo2();// file3.php$obj = new Demo2();class Test1{public function __construct($arg1){echo '对象创建成功,参数是:' . $arg1;}}class Test2{public function __construct($arg1, $arg2){// implode 将索引数组元素组合成字符串echo '对象创建成功,参数是:' . implode(',', [$arg1, $arg2]);}}class Test3{public function __construct($arg1, $arg2, $arg3){echo '对象创建成功,参数是:' . implode(',', [$arg1, $arg2, $arg3]);}}// 工厂类:专用于创建类实例class Factory{// $className:类名 ...$argments:剩余参数,代表实例类需要的参数public static function create($className, ...$argments){return new $className(...$argments);}}//Test1::class 代表该类的完整类名,即 _1205\Test1:完整类名是带有命名空间的// 用工厂类来创建类实例/对象Factory::create(Test1::class, 100);echo '<br>';Factory::create(Test2::class, 100, 200);echo '<br>';Factory::create(Test3::class, 100, 200, 300);

<?php// 定义命名空间namespace _1205;// 依赖注入:解决对象调用之间耦合// 工作类class Person{// 要依赖的外部对象private $car = null;// 在构造方法中将依赖的外部对象实例化public function __construct(){$this->car = new Car();}// 该方法用于外部对象执行外部类中的方法public function work(){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){$this->car = $car;}// 该方法用于外部对象执行外部类中的方法public function work(){return $this->car->drive();}}// 依赖的外部类class Car1{public function drive(){return '我要开车去上班';}}// 实例化类$car = new Car1();$person = new Person1($car);echo $person->work();

制造商类 Maker.php
<?php// 定义命名空间namespace _1205;// 制造商类class Maker{public function get(){return '华为';}}
商品类 Product.php
<?php// 定义命名空间namespace _1205;// 商品类class Product{public function get(Maker $maker){return '该手机是由:<span style="color: green;font-weight: bolder">' . $maker->get() . '</span>生产的';}}
先不用容器来实现
<?php// 定义命名空间namespace _1205;// 引入商品类require 'Product.php';// 引入制造商类require 'Maker.php';// 先不用容器,将制造商类注入到产品类中class Client1{// 输出商品与制造商public function show(){// 创建产品的实例$product = new Product();// 创建制造商的实例$maker = new Maker();// 制造商注入到产品类中return $product->get($maker);}}// 客户端调用echo (new Client1())->show();

容器类 Container.php
<?php// 定义命名空间namespace _1205;// 引入闭包别名use Closure;// 容器类class Container{// 通过该属性来存放类实例,即类实例容器protected $instance = [];// 将类实例化的过程绑定到容器中public function bind($alias, Closure $process){$this->instance[$alias] = $process;}// 将保存在容器中的实例化过程的闭包取出来,并执行它public function make($alias){return $this->instance[$alias]();// return call_user_func_array($this->instance[$alias],[]);}}
用容器类来实现
<?php// 定义命名空间namespace _1205;// 引入生产类require 'Product.php';// 引入制造商类require 'Maker.php';// 引入服务容器类require 'Container.php';class Client2{// 输出商品与制造商public function show(Product $product,Maker $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 Client2())->show($product, $maker);

汽车类 Car.php
<?php// 定义命名空间namespace base\inc1;// 汽车类class Car{public function drive(){return '开汽车';}}
飞机类 Plane.php
<?php// 定义命名空间namespace base\inc1;// 飞机类class Plane{public function drive(){return '乘飞机';}}
火车类 Train.php
<?php// 定义命名空间namespace base\inc1;// 火车类class Train{public function drive(){return '坐火车';}}
自动加载 autoload.php
<?php// 自动加载类文件spl_autoload_register(function ($className){$path = str_replace('\\','/',$className);require dirname(__DIR__) . DIRECTORY_SEPARATOR . $path . '.php';});
传统方式实现
<?php// 定义命名空间namespace base;// 设置引用的外部类名的别名use base\inc1\Car;use base\inc1\Train;use base\inc1\Plane;// 引入自动加载类文件require __DIR__ . '/autoload.php';// 旅行类:使用最传统的方式class Travel1{// 交通工具private $vehicle;// 构造方法,实现用于判断要实例化哪个类public function __construct($vehicle){switch (strtolower($vehicle)) { // 将参数值全部转为小写case 'car':$this->vehicle = new Car();break;case 'train':$this->vehicle = new Train();break;case 'plane':$this->vehicle = new Plane();}}// 调用外部的一个依赖对象,实现其方法public function travelModel(){return $this->vehicle->drive() . '去旅行';}}// 客户端调用echo (new Travel1('car'))->travelModel(), '<br>';echo (new Travel1('train'))->travelModel(), '<br>';echo (new Travel1('plane'))->travelModel(), '<br>';

通过工厂方法实现
<?php// 定义命名空间namespace base;// 设置引用的外部类名的别名use base\inc1\Car;use base\inc1\Plane;use base\inc1\Train;// 自动加载require __DIR__ . '/autoload.php';// 工厂类,专用于创建类实例class Factory{// 该类属性用于表示要创建的类的实例protected static $instance = null;// 判断要创建哪个类的实例public static function getInstance($vehicle){switch (strtolower($vehicle)){case 'car':self::$instance = new Car();break;case 'train':self::$instance = new Train();break;case 'plane':self::$instance = new Plane();}// 返回当前具体的交通工具return self::$instance;}}class Travel2{// 表示交通工具private $vehicle;// 构造方法public function __construct($vehicle){// 调用工厂类的方法创建类实例$this->vehicle = Factory::getInstance($vehicle);}// 调用外部的一个依赖对象public function travelModel(){return $this->vehicle->drive() . '和她一块去旅行';}}// 客户端调用echo (new Travel2('car'))->travelModel(), '<br>';echo (new Travel2('plane'))->travelModel(), '<br>';echo (new Travel2('train'))->travelModel(), '<br>';

定义接口
<?php// 定义命名空间namespace base\inc2;// 交通工具的接口interface iVehicle{public function drive();}
实现接口
<?php// 定义命名空间namespace base\inc2;// 汽车类实现交通工具接口class Car implements iVehicle{public function drive(){return '开汽车';}}
<?php// 定义命名空间namespace base\inc2;// 飞机类实现交通工具接口class Plane implements iVehicle{public function drive(){return '乘飞机';}}
<?php// 定义命名空间namespace base\inc2;// 火车类实现交通工具类接口class Train implements iVehicle{public function drive(){return '坐火车';}}
<?php// 定义命名空间namespace base\inc2;// 轮船类实现交通工具接口class Ship implements iVehicle{public function drive(){return '坐游轮';}}
面向接口编程
<?php// 定义命名空间namespace base;// 设置引用的外部类的别名use base\inc2\Car;use base\inc2\Train;use base\inc2\Plane;use base\inc2\Ship;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() . '-------去旅行';}}// 客户端调用$car = new Car();echo (new Travel3($car))->travelModel(), '<br>';echo (new Travel3(new Plane()))->travelModel(), '<br>';echo (new Travel3(new Train()))->travelModel(), '<br>';echo (new Travel3(new Ship()))->travelModel(), '<br>';


单例模式:创建类的唯一实例
工厂模式:批量创建类实例,大大简化了创建类实例的过程
依赖注入就是将外部对象以参数的形式传入到普通方法或构造方法的参数中,从而实现注入到类中
服务容器就是将类的实例和实例化方法统一管理
面向接口编程可以统一类的实例化过程
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号