Easy access to the php design mode and easy access to the design mode
Problems solved by visitor Mode
In our code writing process, we often need to add some code to some similar objects. Let's take the components of printing a computer object as an example:
/*** Abstract base class */abstract class Unit {/*** get name */abstract public function getName ();} /*** Cpu class */class Cpu extends Unit {public function getName () {return 'I am cpu ';}} /*** Memory class */class memory extends Unit {public function getName () {return 'I am Memory ';}} /*** Keyboard class */class keyboard extends Unit {public function getName () {return 'I am keyboard ';}} /*** Computer class */class Computer {protected $ _ items = []; public function add (Unit $ unit) {$ this-> _ items [] = $ unit;} public function print () {// print each component in a loop foreach ($ this-> _ items as $ item) {$ item-> getName ();}}}
The above code looks perfect at this time, but the problem arises. Now we need to not only print the components, but also save each component to the database, you also need to print the prices of each component. At this time, if you add the getPrice () and save () methods to the Unit base class, you can also implement the desired functions, but there are also problems in doing so, you don't know what else to add. If you use this method to add each new operation, our class will become bloated.
Visitor mode implementation
The visitor mode is designed to solve this problem. It frees the coupling between the data structure and the operations acting on the structure, allowing the operation set to evolve freely, let's take a look at the improved code below:
/*** Abstract base class */abstract class Unit {/*** get the name */abstract public function getName ();/*** used to accept the visitor object, calls back the Visitor's visit method * Key method */public function accept (visitor $ Visitor) {$ method = visit. get_class ($ this); if (method_exists ($ visitor, $ method) {$ visitor-> $ method ($ this );}}} /*** Cpu class */class Cpu extends Unit {public function getName () {return 'I am cpu ';}} /*** Memory class */class Memory extends Unit {public function getName () {return 'I am memory ';}} /*** Keyboard class */class Keyboard extends Unit {public function getName () {return 'I am keyboard ';}} /*** Keyboard class */interface Visitor {public function visitCpu (Cpu $ cpu); public function visitMemory (Memory $ memory); public function visitKeyboard (Keyboard $ keyboard );} /*****/class PrintVisitor implements Visitor {public function visitCpu (Cpu $ cpu) {echo "hello ,". $ cpu-> getName (). "\ n";} public function visitMemory (Memory $ memory) {echo "hello ,". $ memory-> getName (). "\ n";} public function visitKeyboard (Keyboard $ keyboard) {echo "hello ,". $ keyboard-> getName (). "\ n" ;}}/*****/class Computer {protected $ _ items = []; public function add (Unit $ unit) {$ this-> _ items [] = $ unit;}/*** call the accept method of each component */public function accept (Visitor $ visitor) {foreach ($ this-> _ items as $ item) {$ item-> accept ($ visitor) ;}}$ computer = new Computer (); $ computer-> add (new Cpu (); $ computer-> add (new Memory (); $ computer-> add (new Keyboard ()); $ printVisitor = new PrintVisitor (); $ computer-> print ($ printVisitor); // the above Code will print hello, I am cpu hello, I am memory hello, I am keyboard
Summary
After the above improvements, it is very easy for us to expand. If we need to add a method to save data to the database, we can add a class that implements Visitor, such as SaveVisitor, the method for saving in this class is equivalent to extracting the class from some operations in this class, and the object integrating the class operation is the visitor.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.