使用观察者模式处理错误信息
使用观察者模式处理异常信息
异常信息的捕获对编程测试有着重要的意义,这里结合观察者模式,探索如何处理异常信息。
关于观察者模式,如果还没有接触过的话,博客园有很多优秀的博友做了详细的 解释。笔者觉得,所谓观察者模式,必须有两个重要组成部分:一个主题对象,多个观察者。在使用的时候,我们可以将观察者像插头一样插到主题对象这个插座上,利用主题对象完成相应功能。
既然观察者要作为插头,必须要有一个统一的口径才能插到相同的插座上,因而先定义一个接口,Exception_Observer.php:
<span style="color: #000000;">php </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 定义的规范 </span><span style="color: #008000;">*/</span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> Exception_Observer{ </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> update(Observer_Exception <span style="color: #800080;">$e</span><span style="color: #000000;">);} </span>?>
相对于众多观察者,我们首先应该关注唯一的主题对象,Observer_Exception.php:
<span style="color: #000000;">php</span><span style="color: #0000ff;">class</span> Observer_exception <span style="color: #0000ff;">extends</span> <span style="color: #0000ff;">Exception</span><span style="color: #000000;">{ </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$_observers</span>=<span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> attach(Exception_Observer <span style="color: #800080;">$observer</span><span style="color: #000000;">){ self</span>::<span style="color: #800080;">$_observers</span>[]=<span style="color: #800080;">$observer</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$message</span>=<span style="color: #0000ff;">null</span>,<span style="color: #800080;">$code</span>=0<span style="color: #000000;">){ parent</span>::__construct(<span style="color: #800080;">$message</span>,<span style="color: #800080;">$code</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #000000;">notify(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> notify(){ </span><span style="color: #0000ff;">foreach</span> (self::<span style="color: #800080;">$_observers</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$observer</span><span style="color: #000000;">) { </span><span style="color: #800080;">$observer</span>->update(<span style="color: #800080;">$this</span><span style="color: #000000;">); } }}</span>
我们可以清楚地看到,静态变量$_observers用来放置插入的观察者,notify()用来通知所有观察者对象。
这里需要注意 $observer->update($this); 里面 $this 的用法,很多初学者会感到“原来 $this 也可以这么用啊”。
一个小问题: $_observers 不是静态变量可不可以? 这个问题我们后面回答。
定义两个观察者,原则上实现接口所定义的功能。
Email_Exception_Observer.php:
<span style="color: #0000ff;">class</span> Emailing_Exception_Observer <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Exception_Observer{ </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_email</span>="[email protected]"<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$email</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$email</span>!==<span style="color: #0000ff;">null</span>&&filter_var(<span style="color: #800080;">$email</span>,<span style="color: #000000;">FILTER_VALIDATE_EMAIL)) { </span><span style="color: #800080;">$this</span>->_email=<span style="color: #800080;">$email</span><span style="color: #000000;">; } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> update(Observer_Exception <span style="color: #800080;">$e</span><span style="color: #000000;">){ </span><span style="color: #800080;">$message</span>="时间".<span style="color: #008080;">date</span>("Y-m-d H:i:s").<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="信息".<span style="color: #800080;">$e</span>->getMessage().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="追踪信息".<span style="color: #800080;">$e</span>->getTraceAsString().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="文件".<span style="color: #800080;">$e</span>->getFile().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="行号".<span style="color: #800080;">$e</span>->getLine().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #008080;">error_log</span>(<span style="color: #800080;">$message</span>,1,<span style="color: #800080;">$this</span>-><span style="color: #000000;">_email); }}</span>
Logging_Exception_Observer.php:
<span style="color: #000000;">php </span><span style="color: #0000ff;">class</span> Logging_Exception_Observer <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Exception_Observer{ </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_filename</span>="F:/logException.log"<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$filename</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$filename</span>!==<span style="color: #0000ff;">null</span>&&<span style="color: #008080;">is_string</span>(<span style="color: #800080;">$filename</span><span style="color: #000000;">)) { </span><span style="color: #800080;">$thvis</span>->_filename=<span style="color: #800080;">$filename</span><span style="color: #000000;">; } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> update(Observer_Exception <span style="color: #800080;">$e</span><span style="color: #000000;">){ </span><span style="color: #800080;">$message</span>="时间".<span style="color: #008080;">date</span>("Y-m-d H:i:s").<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="信息".<span style="color: #800080;">$e</span>->getMessage().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="追踪信息".<span style="color: #800080;">$e</span>->getTraceAsString().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="文件".<span style="color: #800080;">$e</span>->getFile().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #800080;">$message</span>.="行号".<span style="color: #800080;">$e</span>->getLine().<span style="color: #ff00ff;">PHP_EOL</span><span style="color: #000000;">; </span><span style="color: #008080;">error_log</span>(<span style="color: #800080;">$message</span>,3,<span style="color: #800080;">$this</span>-><span style="color: #000000;">_filename); }}</span>
设计完所有该有的主体对象和插件,我们做个小小的测试:
<span style="color: #000000;">php </span><span style="color: #0000ff;">require</span> 'Exception_Observer.php'<span style="color: #000000;">;</span><span style="color: #0000ff;">require</span> 'Observer_Exception.php'<span style="color: #000000;">;</span><span style="color: #0000ff;">require</span> 'Logging_Exception_Observer.php'<span style="color: #000000;">;</span><span style="color: #0000ff;">require</span> 'Emailing_Exception_Observer.php'<span style="color: #000000;">;Observer_Exception</span>::attach(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Logging_Exception_Observer());</span><span style="color: #0000ff;">class</span> MyException <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Observer_Exception{ </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> 'this is a test'<span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> test1(){ </span><span style="color: #0000ff;">echo</span> "我是自定义的方法处理这个异常"<span style="color: #000000;">; }}</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> MyException("出现异常,记录一下"<span style="color: #000000;">); } </span><span style="color: #0000ff;">catch</span> (MyException <span style="color: #800080;">$e</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$e</span>-><span style="color: #000000;">getMessage(); </span><span style="color: #0000ff;">echo</span> "<ht></ht>"<span style="color: #000000;">; }</span>?>
本实例首先先加载观察者,其后进行其他操作。回到上面提出的问题, $_observers 可以不是静态变量吗?答案是不可以。如果 $_observers 不是静态变量,加载观察者的行为对后续操作没有影响。static让所有实例成员共享某个变量。即便类继承也同样有效。有兴趣的可以继续探索下static的神奇作用吧。
本例显示输出与一般情况无异,但不同的是已在自定义的文件下生成了相应的日志。虽然最后实现的功能再简单不过,很多人甚至可以用更少的代码更简单的方法实现,但是,在实现更加复杂系统的情况下,观察者模式给我们带来很大方便。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이번 장에서는 CakePHP의 환경 변수, 일반 구성, 데이터베이스 구성, 이메일 구성에 대해 알아봅니다.

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는
