批改状态:未批改
老师批语:
<?phpnamespace _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(){// 实例化当前类,并返回类实例/对象// 判断当前类是否已经被实例化过了,如果没有的话就实例化,如果已实例化,就返回它//is_null()这个函数用来判断变量值是否为null,如果是null,返回true否则falseif (is_null(self::$instance)) {//在当前类中调用类属性,使用self,同时self也是类本身//对类进行实例化new self(),然后返回类实例对象,保存在变量$instance当中self::$instance = new self();}//如果已经实例化,返回类实例对象本身return self::$instance;}// 禁用克隆魔术方法private function __clone(){// ...}}//new Demo1();$obj1 = Demo1::getInstance();$obj2 = Demo1::getInstance();//查看两个实例对象是否完全相同var_dump($obj1 === $obj2);echo '<br>';//查看两个对象的类型var_dump($obj1, $obj2);echo '<hr>';

<?php// 单例模型应用场景class Db{// 构造方法私有化 禁止外部调用//...$connectParams是可变参数...$connectParams===$dsn,$username,$passwordprivate function __construct(...$connectParams){//初始化变量$dsn = $connectParams[0];$username = $connectParams[1];$password = $connectParams[2];//连接数据库self::$pdo = new \PDO($dsn, $username, $password);}// 目前 由于构造方法的私有化,所以只能在类中的内部将类实例化// 当前类的实例 静态属性public static $pdo = null;// 实例化当前类的方法public static function getInstance(...$connectParams){// 实例化当前类,并返回类实例/对象// 判断当前类是否已经被实例化过了,如果没有的话就实例化,如果已实例化,就返回它if (is_null(self::$pdo)) {// 构造函数不需要返回,这里需要特别注意new self(...$connectParams);}//返回数据库连接return self::$pdo;}// 禁用克隆魔术方法private function __clone(){// ...}}echo '<hr>';//客户端调用//配置数据库连接参数$dsn,$username,$password$connectParams = ['mysql:host=localhost;dbname=mt', 'root', '111'];//实例化同时,传入数据库连接参数,连接数据库$pdo = Db::getInstance(...$connectParams);//这里直接调用了query()方法,是为了简便演示进程,没有使用预处理过程,一般数据是从数据库中获取//在这里直接打印输出//PDO中的query和fetchAll方法echo '<pre>' .print_r($pdo->query('SELECT * FROM `user`')->fetchAll(),true) .'</pre>';

<?phpnamespace _1205;// 工厂模式: 用于批量创建类的实例/对象use mvc\Facade;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){echo '对象创建成功, 参数是: ' . implode(', ', [$arg1, $arg2]);}}class Test3{public function __construct($arg1, $arg2, $arg3){//implode(',',[$arg1,$arg2,$arg3])= '$arg1,$arg2,$arg3';echo '对象创建成功, 参数是: ' . implode(', ', [$arg1, $arg2, $arg3]);}}// 工厂类, 专用于创建类实例class Factory{//静态方法 $className 类名 ...$arguments是可变变量public static function create($className, ...$arguments){//根据传过来的类名和参数,对类进行实例化,并返回实例对象return new $className(...$arguments);}}//echo Test1::class; // _1205\Test1: 完整的类名, 带有命名空间的//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 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){//根据外部传入参数来对私有属性$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(){//此时的$this->vehicle就是某个类的实例化对象,所以会调用相应类中的方法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\Train;use base\inc1\Plane;use base\inc1\Ship;require __DIR__ . '/autoload.php';// 工厂类, 专用于创建类实例class Factory{//添加静态变量static $instance 用于存储类实例protected static $instance = null;//外部传入参数,得到相应类的实例对象public static function getInstance($vehicle){switch (strtolower($vehicle)) {case 'car'://类内调用该类属性使用self::self::$instance = new Car();break;case 'train':self::$instance = new Train();break;case 'ship':self::$instance = new Ship();break;case 'plane':self::$instance = new Plane();}// 返回当前具体的交通工具return self::$instance;}}class Travel2{// 交通工具private $vehicle;// 构造方法public function __construct($vehicle){//Factory::getInstance($vehicle)==self::$instance//此时的$this->vehicle就是Factory::getInstance($vehicle)==self::$instance//就是一个类实例$this->vehicle = Factory::getInstance($vehicle);}// 调用外部一个依赖对象public function travelModel(){//$this->vehicle是类实例,可以调用相应的类中的方法return $this->vehicle->drive() . ' : @@@@ 去***';}}// 客户端调用echo (new Travel2('car'))->travelModel(), '<br>';echo (new Travel2('train'))->travelModel(), '<br>';echo (new Travel2('plane'))->travelModel(), '<br>';echo (new Travel2('ship'))->travelModel(), '<br>';

<?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初始化$this->vehicle = $vehicle;}// 调用外部一个依赖对象public function travelModel(){return $this->vehicle->drive() . ' : ======= 去旅行';}}// 客户端调用$car = new Car();echo (new Travel3($car))->travelModel(), '<br>';//new Train()作为参数传给new Travel3(),然后调用travelModel()echo (new Travel3(new Train()))->travelModel(), '<br>';echo (new Travel3(new Plane()))->travelModel(), '<br>';echo (new Travel3(new Ship()))->travelModel(), '<br>';

<?phpnamespace _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();

<?phpnamespace _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);


容器中存入了所依赖的类的实例对象队列,并且将类与类实例化代码的闭包函数绑定到容器中,bind()方法是放进去,make()是调用容器中的实例化方法。
类分为工作类和依赖类
工作类中需要调用其它类时,为了降低耦合度,需要将对被依赖的类的实例过程中的new消灭掉,这就是依赖注入的目的。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号