Blogger Information
Blog 27
fans 0
comment 0
visits 17444
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
029-12月05日-PHP第19节-单例、工厂模式、依赖注入、面向接口编程等
冇忉丼
Original
990 people have browsed it

1. 将课堂代码全部上机操作至少一遍以上

单例模式(以pdo操作举例)

  1. <?php
  2. //单例模式
  3. //声明命名空间
  4. namespace _1210;
  5. class Single
  6. {
  7. //构造方法私有后,使外部不能实例化类
  8. private function __construct()
  9. {
  10. }
  11. //无法使用clone方法
  12. private function __clone()
  13. {
  14. // TODO: Implement __clone() method.
  15. }
  16. //类的实例,先赋初值
  17. public static $instance = null;
  18. public static function getInstance()
  19. {
  20. //判断当前类是否已经实例化了,没有就实例化
  21. if(is_null(self::$instance)){
  22. self::$instance = new self();
  23. }
  24. //已经实例化就返回它
  25. return self::$instance;
  26. }
  27. }
  28. $obj1 = Single::getInstance();
  29. $obj2 = Single::getInstance();
  30. var_dump($obj1 === $obj2);
  31. //创建的两个对象一样--单个实例--单例模式
  32. echo '<hr/>';
  33. //应用场景,以数据库连接举例
  34. class Db{
  35. private function __construct(...$connectParams)
  36. {
  37. $dsn = $connectParams[0];
  38. $username = $connectParams[1];
  39. $password = $connectParams[2];
  40. self::$pdo = new \PDO($dsn,$username,$password);
  41. }
  42. public static $pdo = null;
  43. public static function getInstance(...$connectParams)
  44. {
  45. //判断是否实例化了,empty?
  46. if(is_null(self::$pdo)){
  47. //与上面不同的是,这里是构造函数,不用返回self::$instance
  48. new self(...$connectParams);
  49. }
  50. return self::$pdo;
  51. }
  52. }
  53. echo '<br/>';
  54. $connectParams = ['mysql:host=localhost;dbname=anguoguo','root','root'];
  55. $pdo = Db::getInstance(...$connectParams);
  56. print_r($pdo->query('SELECT * FROM `movies`')->fetchAll());

工厂模式

  1. <?php
  2. //工厂模式--流水线生产类的实例
  3. namespace _1210;
  4. //声明工厂类,里面有生产方法,用的是静态方法--new一个实例
  5. class Factory{
  6. public static function create($className,...$params){
  7. return new $className(...$params);
  8. }
  9. }
  10. //声明商品类,有各自的方法
  11. class Goods1{
  12. public function __construct($para1)
  13. {
  14. echo '商品1创建成功,参数为: ' . $para1;
  15. }
  16. }
  17. class Goods2{
  18. public function __construct($para1,$para2)
  19. {
  20. echo '商品2创建成功,参数为: ' . implode(',',[$para1,$para2]);
  21. }
  22. }
  23. class Goods3{
  24. public function __construct($para1,$para2,$para3)
  25. {
  26. echo '商品3创建成功,参数为: ' . implode(',',[$para1,$para2,$para3]);
  27. //implode:数组转为字符串,以,为分隔依据,相对的是explode字符串转为数组,也以第一个参数为划分依据
  28. }
  29. }
  30. //静态方法调用方式,类作为参数时的写法xx::class
  31. Factory::create(Goods1::class,'甲');
  32. echo '<hr/>';
  33. Factory::create(Goods2::class,'甲','乙');
  34. echo '<hr/>';
  35. Factory::create(Goods3::class,'甲','乙','丙');

依赖注入(DI)

  1. <?php
  2. namespace _1210;
  3. //依赖注入:Dependency Injection解决对象调用之间的耦合
  4. class Someone{
  5. private $football = null;//这个类依赖的外部类的对象
  6. public function __construct()
  7. {
  8. $this->football = new Football();//此处将外部对象实例化,此处为外部对象注入点
  9. }
  10. public function relax(){
  11. return $this->football->play();//外部对象执行一个操作
  12. }
  13. }
  14. //依赖的外部类,Football
  15. class Football{
  16. public function play(){
  17. return '休息时踢足球';
  18. }
  19. }
  20. $someone = new Someone();
  21. echo $someone->relax();
  22. echo '<hr/>';
  23. /***************************************************/
  24. //也可以在外部$football = new Football(),前面构造函数处就不用new Football(),直接$football

容器类(将实例与方法放进容器,再取出生成实例)

产品:

  1. <?php
  2. namespace _1210;
  3. class Product
  4. {
  5. public function get(Maker $maker){
  6. return '这辆小钢炮是由:<span style="color:lightblue;font-weight: bolder"> ' .
  7. $maker->get() . '</span>生产';
  8. }
  9. }

生产商:

  1. <?php
  2. namespace _1210;
  3. class Maker{
  4. public function get(){
  5. return '福特';
  6. }
  7. }//生产商

容器:

  1. <?php
  2. namespace _1210;
  3. use Closure;//要用闭包
  4. class Container{
  5. protected $instance = [];//instance例子,即表示实例数组(容器)
  6. //类实例,实例方法绑定到容器中(数组)
  7. public function bind($alias,Closure $process){
  8. $this->instance[$alias] = $process;
  9. }
  10. //从容器中取出实例化过程的闭包,执行它
  11. public function make($alias){
  12. return $this->instance[$alias]();//即$process(),,()代表执行
  13. }
  14. }

容器使用:

  1. <?php
  2. namespace _1210;
  3. require 'Product.php';
  4. require 'Maker.php';//引入外部两个文件,为什么不use类呢
  5. require 'Container.php';//引入了容器类
  6. class Client2{
  7. public function show(Product $product,Maker $maker){
  8. //之前实例化的过程交给容器make,两个参数需要在这里传入吗,与类中参数相关
  9. return $product->get($maker);
  10. }
  11. }
  12. $container = new Container();
  13. $container->bind('product',function (){return new Product();});
  14. $container->bind('maker',function (){return new Maker();});
  15. $product = $container->make('product');
  16. $maker = $container->make('maker');
  17. //以上按照Container类中的流程实例化,绑定,取出执行
  18. echo (new Client2())->show($product,$maker);//称为客户端调用,同时把类实例化,这里是和实例化后的参数相关

面向接口编程

接口(给类定个规范):

  1. <?php
  2. //与inc1比多了接口
  3. namespace base\inc2;
  4. // 休闲方式的接口
  5. interface iBall
  6. {
  7. public function play();//抽象的
  8. }

休闲类(三个,生效自接口)

  1. <?php
  2. //01.Baseball类
  3. namespace base\inc2;
  4. class Baseball implements iBall {
  5. public function play(){
  6. return '打棒球';
  7. }
  8. }
  9. //02.Basketball类
  10. class Basketball implements iBall{
  11. public function play(){
  12. return '玩篮球';
  13. }
  14. }
  15. //03.Football类
  16. class Football implements iBall {
  17. public function play(){
  18. return '玩足球';
  19. }
  20. }

自动加载函数(方便引入多个文件)

  1. <?php
  2. spl_autoload_register(function ($className){//spl_autoload_register函数的参数是一个回调函数,调用该函数会将注册的加载函数放入autoload函数队列中
  3. $path = str_replace('\\','/',$className);
  4. require dirname(__DIR__) . DIRECTORY_SEPARATOR . $path . '.php';
  5. });//自动加载函数,自动加载当前同目录下的$path.php

用法:

  1. <?php
  2. //说明面向接口编程
  3. namespace base;
  4. use base\inc2\Baseball;
  5. use base\inc2\Basketball;
  6. use base\inc2\Football;
  7. use base\inc2\iBall;
  8. //在实例化以上类时,IDE会自动use
  9. require __DIR__ . '/autoload.php';//自动加载,不用require一堆文件了
  10. class Relax3{
  11. //球类
  12. private $ball;
  13. //构造方法
  14. public function __construct(iBall $ball)
  15. {
  16. $this->ball = $ball;
  17. }
  18. //调用外部一个依赖对象
  19. public function relaxModel(){
  20. return $this->ball->play() . ' : 通过接口去放松';
  21. }
  22. }
  23. //客户端调用
  24. $football =new Football();
  25. echo (new Relax3($football))->relaxModel(), '<br/>';
  26. echo (new Relax3(new Baseball()))->relaxModel(), '<br/>';//直接在调用参数的时候实例化类
  27. echo (new Relax3(new Basketball()))->relaxModel(), '<br/>';

2. 手写课堂笔记:1205.md

朱老师,说明一下用作业本书写舒服一点,肯定有装订的。

总结

单例模式:实例就一个,常见于使用PDO建立数据模型
工厂模式:生产N个实例
依赖注入(DI):内部调用外部实例,就不要在内部实例化了,会加重类间耦合,最好在外部实例化,然后将实例作为参数传到调用类的构造方法里
容器:实例和实例化方法都放进去,要用时再拿出来
面向接口:接口是规范类的,使用抽象方法

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:这些东西虽然不多, 却是左右开发工作的利器, 必须重视
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post