Some object-oriented programming methods provide the ability to build complex network interconnection between objects. When objects are connected together, they can provide services and information to each other.
Generally speaking, when the state of an object changes, you still need the object to communicate with each other. But for a variety of reasons, you may not want to make big changes to your code because of changes in your code environment. Perhaps, you just want to improve the communication code according to your specific application environment. Or, you just want to simply reconstruct the communication code to avoid interdependence and dependency between classes and classes.
Problem
How do you notify other objects when the state of an object changes? Is there a need for a dynamic scheme-a scheme that allows free connection, just like a script is allowed to execute?
Solution
Observation mode allows an object to focus on the state of other objects, and the observational pattern provides an observer structure, or a subject and an object, to the observer. The subject, which is the observer, can be used to contact all the observers who have observed it. The object, the Observer, is used to accept changes in the state of the subject.
Observation is the collaboration of a class (i.e. a subject) that can be observed with one or more classes (i.e., objects) that observe it. Whenever the state of the observed object changes, all registered observers will be notified.
The observational model separates the observer (the subject) from the Observer (the object) species. In this way, each observer can take individual actions according to the change of the subject. Observation mode, like Publish/subscribe mode, is an effective model to describe the interaction between objects. )
The observation mode is flexible and powerful. For observers, the additional resource overhead of querying which classes require their own state information and each use of those state information does not exist. In addition, an observer can register and unregister at any appropriate time. You can also define a number of specific observational classes to perform different operations in a practical application.
Instance Code
For example, you can use observation mode for your PHP script to create a more flexible handle for logging errors. Because the default error record handle may only display some error messages on the screen. However, the enhanced handle can also write error messages in a log file, or write error messages into the system log, or send an error message through e-mail or use a sound to report an error message. You can even construct a level error scheme that only allows observers who have registered for specific error messages to report. Serious error messages, such as database failures, can be reported from general warning messages.
Below, we use observational mode to create a series of classes for PHP to implement the functions that we just mentioned. Create a new class called ErrorHandler, which is the subject of the observation pattern, the observed. Another two classes, called Fileerrorlogger and Emailerrorlogger, are the observed objects (i.e. observers). The Fileerrorlogger class writes an error message to the log file, and the Emailerrorlogger class uses e-mail to send an error message. In UML, you can represent the following:
In order to implement the error record handle based on the observation pattern, we first notice that the Fileerrorlogger class and the Emailerrorlogger class as the Observer do nothing. So how does the Fileerrorlogger class write the wrong message to a file, and how does the Emailerrorlogger class send e-mail? Next, let me take a look at the technical details used to implement the observation pattern, and then focus on the details of the main body ――errorhandler of the pattern. Finally, write some error handling functions to invoke this ErrorHandler class.
Finally, the following code is used to indicate:
PHP4
$eh =& getErrorHandlerInstance();
$eh->attach(new EmailErrorLogger (‘jsweat_php@yahoo.com’));
$eh->attach(new FileErrorLogger(fopen (‘error.log’,’w’)));
set_error_handler (‘observer_error_handler’);
// ... later
trigger_error(‘this is an error’);
The ErrorHandler class is a single piece mode (refer to the 4th Chapter: the Singleton pattern). It can register various error information observers through function attach (), and the Set_error_handler () function is a function that points to the ErrorHandler class. Finally, when an error message is triggered, all observers will be notified.
In order for this observation to take effect, your test must prove that all of these operations (write the error message to the log, use email to send the error message) can be executed and work correctly. In short, let's take a look at a series of simple tests. (Additional examples related to this example can be found in the source code included in this book)
Here's a piece of code for the Fileerrorlogger class Joint test: It tests the ability to write logs to a file when the Fileerrorlogger class is instantiated by an object.
class FileErrorLoggerTestCase extends UnitTestCase {
var $_fh;
var $_test_file = ‘test.log’;
function setup() {
@unlink($this->_test_file);
$this->_fh = fopen ($this->_test_file, ‘w’);
}
function TestRequiresFileHandleToInstantiate() { /* ... */ }
function TestWrite() {
$content = ‘test’.rand(10,100);
$log =& new FileErrorLogger ($this->_fh);
$log->write($content);
$file_contents = file_get_contents ($this->_test_file);
$this->assertWantedPattern (‘/’.$content.’$/’, $file_contents);
}
function TestWriteIsTimeStamped() { /* ... */ }
}