欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php设计模式之单例模式学习

程序员文章站 2022-05-17 15:03:30
...
  1. class A{
  2. private function __construct(){}
  3. }
  4. $a = new A();
  5. ?>
复制代码

程序运行结果为: Fatal error: Call to private A::__construct() from invalid context in E:\PHPProjects\test.php on line 6

我们已经禁止外部用new实例化这个类,我们改如何让用户访问这个类呢?前门堵了,我们需要给用户留个后门。 解决办法是:static 修饰的方法,可以不经实例化一个类就可以直接访问这个方法。 //不能用new实例化的类.
//static的方法留给外部访问.
//在方法内部返回实例.

  1. class A{
  2. private function __construct(){}
  3. static function getClassA(){
  4. $a = new A();
  5. return $a;
  6. }
  7. }
  8. // 看到这里确实返回的是 A 的实例.但不是同一个对象.
  9. $a1 = A::getClassA();
  10. $a2 = A::getClassA();
  11. echo "\$a1 的类是 ".get_class($a1)." , \$a2 是 ".get_class($a1);
  12. if($a1 === $a2){
  13. echo "
    \$a1 \$a2 指向同一对象.";
  14. }else{
  15. echo "
    \$a1 \$a2 不是一个对象.";
  16. }
  17. ?>
复制代码

程序运行结果为: $a1 的类是 A , $a2 是 A $a1 $a2 不是一个对象.

我们已经通过static方法返回了A的实例。但还有问题。我们如何保证我们多次操作获得的是同一个实例的呢?

解决办法: static的属性在内部也只有一个。 static 属性能有效的被静态方法调用。将这个属性也设置成private,以防止外部调用。 先将这个属性设置成 null。每次返回对象前,先判断这个属性是否为 null 。 如果为 null 就创建这个类的新实例,并赋值给这个 static 属性。如果不为空,就返回这个指向实例的 static 属性。 //不能用new实例化的类.
//static的方法留给外部访问.
//在方法内部返回实例.
//定义静态属性保证这个实例能被静态方法调用.
//增加判断部分.

  1. class A{
  2. private static $a = null;
  3. private function __construct(){}
  4. static function getClassA(){
  5. if( null == self::$a){
  6. self::$a = new A();
  7. }
  8. return self::$a;
  9. }
  10. }
  11. // 看到这里确实返回的是 A 的实例.但不是同一个对象.
  12. $a1 = A::getClassA();
  13. $a2 = A::getClassA();
  14. echo "\$a1 的类是 ".get_class($a1)." , \$a2 是 ".get_class($a1);
  15. if($a1 === $a2){
  16. echo "
    \$a1 \$a2 指向同一对象.";
  17. }else{
  18. echo "
    \$a1 \$a2 不是一个对象.";
  19. }
  20. ?>
复制代码

程序运行结果为: $a1 的类是 A , $a2 是 A $a1 $a2 指向同一对象.

到此,我们写了一个最简单的单例模式 。 现在,你可以尝试写一个应用单例设计模式的数据库连接类。 要记住单例模式的使用效果和书写方式。