PHP类规则和设计模式

一、类的规则

  1. 一个文件中只能放一个类(必须的)
  2. 文件名和类名同名(必须的)
  3. 类文件以.class.php结尾(不是必须的)

1.1 手动加载类

在项目开发中,因为一个文件中只能写一个类,并且在执行过程中会有很多的类参与,我们先演示手动一个个加载类。
项目结构如下:

php
├── Book.class.php
├── Goods.class.php
├── index.php
├── Phone.class.php

Book.class.php代码如下:

<?php
// 图书类
    class Book extends Goods {
    
    
        public function getName () {
    
    
            echo "《{
      
      $this->name}》<br/>";
        }
    } 
?>

Good.class.php代码如下:

<?php
    // 商品类
    abstract class Goods {
    
    
        protected $name;
        final public function setName ($name) {
    
    
            $this->name = $name;
        }
        public abstract function getName();
    }
?>

index.php代码如下:

<?php
require './Goods.class.php';
require './Book.class.php';
require './Phone.class.php';
    // 测试
    $book = new Book();
    $book -> setName('面向对象编程');
    $phone = new Phone();
    $phone -> setName('华为');
    $book -> getName();
    $phone -> getName();
?>

Phone.class.php代码如下:

<?php
    // 电话类
    class Phone extends Goods {
    
    
        public function getName () {
    
    
            echo $this->name,'<br/>';
        }
    }
?>

运行结果如下:
在这里插入图片描述
可以看到,我们这边一个个的手动去加载类非常的麻烦,下面介绍自动加载类。

1.2 自动加载类

在项目开发中,因为一个文件中只能写一个类,并且在执行过程中会有很多的类参与,如果一个一个的加载很麻烦,所以,就需要一个机制实现在PHP执行过程中自动加载需要的类。

1.2.1 __autoload()函数

方法一:__autoload()函数
当缺少类的时候自动的调用__autoload()函数,并且将缺少的类名作为参数传递给__autoload()。

项目结构还是如下:

php
├── Book.class.php
├── Goods.class.php
├── index.php
├── Phone.class.php

改变index.php中的内容如下(其他不改变):

<?php
// 自动加载类
function __autoload ($class_name) {
    
    
    require "./{
      
      $class_name}.class.php";
}
    // 测试
    $book = new Book();
    $book -> setName('面向对象编程');
    $phone = new Phone();
    $phone -> setName('华为');
    $book -> getName();
    $phone -> getName();
?>

效果如下:
在这里插入图片描述

可以看到我们使用了自动加载类,可以很方便。
但是注意:__autoload()函数在PHP7.2以后就不支持了。

1.2.2 spl_autoload_register()

注册__autoload()函数
项目结构还是不变。
index.php改为如下:

<?php

// 方法一
function loadClass ($class_name) {
    
    
    require "./{
      
      $class_name}.class.php";
}
//注册加载类函数
spl_autoload_register('loadClass');

// 方法二 
// spl_autoload_register(function  ($class_name) {
    
    
//     require "./{$class_name}.class.php";
// });


    // 测试
    $book = new Book();
    $book -> setName('面向对象编程');
    $phone = new Phone();
    $phone -> setName('华为');
    $book -> getName();
    $phone -> getName();
?>

效果:
在这里插入图片描述
也可以注册多个函数(以队列的形式,先进先出),进行(区分)不同类的加载。

1.3 类文件存储不规则

类文件存储不规则的加载方法,将类名和文件地址做一个映射,组成一个关联数组。
代码如下:

<?php
spl_autoload_register(function ($class_name) {
    
    
    // 类名和文件地址映射成一个关联数组
    $map = array(
        'Goods' => './aa/Goods.class.php',
        'Book' => './bb/Book.class.php',
        'Phone' => './cc/Phone.class.php'
    );
    // 在映射数组中找到就包含
    if (isset($map[$class_name])) {
    
    
        require $map[$class_name];
    }
})

    // 测试
    $book = new Book();
    $book -> setName('面向对象编程');
    $phone = new Phone();
    $phone -> setName('华为');
    $book -> getName();
    $phone -> getName();
?>

在项目中,绝大部分都是规则存储的,不规则的比较少。

二、clone和__clone()

创建对象的方式有哪些?
方法一:实例化
方法二:克隆
例题:

<?php
class Student {
    
    

}
$stu1=new Student;
$stu2=new Student;
var_dump($stu1,$stu2);

?>

效果:
在这里插入图片描述


<?php
class Student {
    
    

}
$stu1=new Student;
$stu2=$stu1;
var_dump($stu1,$stu2);

?>

效果:
在这里插入图片描述


<?php
class Student {
    
    

}
$stu1=new Student;
$stu2=clone $stu1;
var_dump($stu1,$stu2);

?>

效果:
在这里插入图片描述


__clone()函数在调用clone指令的时候自动调用。
例题:

<?php
class Student {
    
    
    public function __clone() {
    
    
        echo '正在克隆';
    }
}
$stu1=new Student;
$stu2=clone $stu1;
var_dump($stu1,$stu2);

?>

效果:
在这里插入图片描述
小结:
1、clone是创建对象的方法之一
2、当执行clone指令的时候,会自动的调用__clone()方法

三、设计模式

3.1 单例模式

一个类只能有一个对象。
应用场景:多次请求的数据库只需要一个连接对象。
实现:三私一公

1、私有的静态属性用来保存对象单例。
2、私有的构造方法用来阻止在类的外部实例化。
3、私有的__clone阻止在类的外部clone对象。
4、公有的静态方法用来获取对象的单例。

代码:

<?php
// 三私一公
class DB {
    
    
    // 私有的静态属性用来保存单例
    private static $instance;
    // 私有的构造方法阻止在类的外部实例化
    private function __construct() {
    
    

    }
    // 私有的__clone()阻止在类的外部克隆对象
    private function __clone() {
    
    

    }
    // 公有的方法用来获取单例
    public static function getInstance () {
    
    
        if (!self::$instance instanceof self) {
    
    
            self::$instance = new self();
        }
        return self::$instance;
    }
}
$db1 = DB::getInstance();
// $db2 = clone $db1;
$db2 = DB::getInstance();
var_dump($db1, $db2)

?>

效果:
在这里插入图片描述

3.2 工厂模式

特点:传递不同的参数调用不同的策略。(方法)

<?php
    class ProductsA {
    
    

    }
    class ProductsB {
    
    

    }
    class Factory {
    
    
        public function create($num) {
    
    
            switch ($num) {
    
    
                case 1: 
                    return new ProductsA;
                case 2: 
                    return new ProductsB;
                default:
                    return null;
            }
        }
    }

    // 测试
    $factory = new Factory();
    $obj1 = $factory->create(1);
    $obj2 = $factory->create(2);
    var_dump($obj1, $obj2);
?>

效果:
在这里插入图片描述

3.3 策略模式

特点:传递不同的参数调用不同的策略(方法)

<?php
    class Walk {
    
    
        public function way() {
    
    
            echo '走着去<br/>';
        }
    }
    class Bus {
    
    
        public function way() {
    
    
            echo '坐车去<br/>';
        }
    }
    // 策略模式
    class Student {
    
    
        public function play ($obj) {
    
    
            $obj->way();
        }
    }
    // 测试
    $stu = new Student;
    // $stu->play(new Walk()); // 走着去
    $stu->play(new Bus()); // 坐车去
?>

在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

猜你喜欢

转载自blog.csdn.net/weixin_44103733/article/details/108157535
今日推荐