设为首页 收藏本站
查看: 572|回复: 0

[经验分享] PHP类实例教程(十四):设计模式之单件模式

[复制链接]

尚未签到

发表于 2017-4-9 10:52:38 | 显示全部楼层 |阅读模式
  单件模式要解决的问题就是“如何让这个类只有一个实例”。
  我们的web应用中,大量使用了数据库连接,如果反复建立与数据库的连接必然消耗更多的系统资源。
  我们如何解决这个问题,建立唯一的数据库连接是必要的方式。
  我们又如何知道与这个数据库的连接是否已经建立? 还是需要现在建立?
  单件模式可以解决这个问题。
  先假设我们需要一个类完成在内存中只有一份的功能,我们该如何做呢?
  我们一步一步的使用前面学过的知识来写一个单件的例子。
  问题1:
  前面学过,每次用new 类名的方式,就可以创建一个对象。
  我们必须禁止外部程序用 new 类名的方式来创建多个实例。
  解决办法:
  我们将构造函数设置成private ,让构造函数只能在内部被调用,而外部不能调用。
  这样,这个类就不能被外部用 new 的方式建立多个实例了。
  不能被外部用new实例化的类。
  <?phpclass A{private function __construct() {}}?>
  问题2:
  我们已经禁止外部用new实例化这个类,我们改如何让用户访问这个类呢?前门堵了,我们需要给用户留个后门。
  解决办法:
  static 修饰的方法,可以不经实例化一个类就可以直接访问这个方法。
  后门就在这里。
  <?phpclass A{private function __construct() {}static function getClassA() {return "这里是后门,可以通过这里进入这个类的内部";}}echo A::getClassA();?>
  问题3:
  虽然我们已经进入类内部,但我们要的是这个类的唯一实例?
  先不管别的,我们先需要一个实例。
  通过这个static的方法返回这个实例,如何做呢?
  解决办法:
  private的构造函数,不能被外部实例化。
  但是我们已经成功潜入类的内部了(间谍?007?),我们在内部当然可以调用private的方法创建对象。
  我们这样做看看。
  下面的例子我们确实返回了A类的实例,但注意两次执行返回的不是同一个实例。
  <?phpclass A{private function __construct() {}static function getClassA() {$a = new A();return $a;}}$a1 = A::getClassA();$a2 = A::getClassA();echo "/$a1的类是" . get_class($a1) . ", /$a2是" . get_class($a2);if ($a1 === $a2) {echo "<br />/$a1 /$a2指向同一个对象。";} else {echo "<br />/$a1 /$a2不是同一个对象。";}?>
  问题4:
  我们已经通过static方法返回了A的实例。但还有问题。
  我们如何保证我们多次操作获得的是同一个实例的呢?
  解决办法:
  static的属性在内部也只有一个。
  static 属性能有效的被静态方法调用。
  将这个属性也设置成private,以防止外部调用。
  先将这个属性设置成 null。
  每次返回对象前,先判断这个属性是否为null 。
  如果为null 就创建这个类的新实例,并赋值给这个 static 属性。
  如果不为空,就返回这个指向实例的static 属性。
  <?phpclass A{private static $link = null;private function __construct() {}static function getClassA() {if (null == self::$link) {self::$link = new A();}return self::$link;  }}$a1 = A::getClassA();$a2 = A::getClassA();echo "/$a1的类是" . get_class($a1) . ", /$a2是" . get_class($a2);if ($a1 === $a2) {echo "<br />/$a1 /$a2指向同一个对象。";} else {echo "<br />/$a1 /$a2不是同一个对象。";}?>
  到此,我们写了一个最简单的单件模式 。
  现在,你可以尝试写一个应用单件设计模式的数据库连接类。
  要记住单件模式的使用效果和书写方式。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362328-1-1.html 上篇帖子: 用PHP实现标准的IP Whois查询 下篇帖子: PHP类实例教程(四):PHP5类中的方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表