Talking about PHP object-oriented visitor mode + combination mode, talking about object-oriented

Source: Internet
Author: User

Talking about PHP object-oriented visitor mode + combination mode, talking about object-oriented

Because the original text continues the code example of the combination mode to show the visitor mode, we will merge the code here to review it. However, we mainly focus on the visitor mode. As the name suggests, this model has a visitor class (just like the examiner in the recent hot play "people's name", who ran to the home of the corrupt official to investigate and obtain evidence, and then convicted after the investigation ), when the visitor class calls the visitor class, it will pass itself to it for use.

View the Code directly:

// Base class abstract class Unit {abstract function bombardStrength (); // obtain the Unit's attack power // This method will call the visitor class, and pass it to function accept (ArmyVisitor $ visitor) {$ method = "visit ". get_class ($ this); $ visitor-> $ method ($ this); // call the method of the visitor class, where "visit" is used ". get_class ($ this) forms the name of the method} // according to the original article, it is used to set a depth, although this method will be called later, it is not important to understand this mode. (In the original sample code, there are often some codes that do not have much to do with understanding the mode principle) protected function setDepth ($ depth) {$ this-> depth = $ depth;} func Tion getDepth () {return $ this-> depth; }}// Archer class Archer extends Unit {function bombardStrength () {return 4 ;}} // laser gun class LaserCannonUnit extends Unit {function bombardStrength () {return 44 ;}// Cavalry class Cavalry extends Unit {function bombardStrength () {return 2; // is the cavalry less powerful than the archer?} // Used to combine instances that inherit the unit class and let the Army and TroopCarrier classes inherit the removeUnit and addUnit methods, the base class is not put because the above three classes are already the smallest units, and the removeUnit and addUnit methods are not useful to them. Abstract class CompositeUnit extends Unit {private $ units = array (); // stores any instance function getComposite () that inherits the unit class () {// this method is mainly used to determine whether the current instance is a CompositeUnit class return $ this;} protected function units () {return $ this-> units;} function removeUnit (Unit $ unit) {// delete a military unit $ this-> units = array_udiff ($ this-> units, array ($ unit), function ($ a, $ B) {return ($ a ===$ B )? ;});} Function addUnit (Unit $ unit) {// Add a military unit if (in_array ($ Unit, $ this-> units, true) {return ;} $ unit-> setDepth ($ this-> depth + 1); $ this-> units [] = $ unit;} function bombardStrength () {$ ret = 0; foreach ($ this-> units as $ unit) {$ ret + = $ unit-> bombardStrength ();} return $ ret;} function accept (Armyvisitor $ visitor) {// call the visitor parent: accept ($ visitor); // call the accept method of the base class, in the first client code entry, an overall information fo of the military group will be saved. Reach ($ this-> units as $ thisunit) {// call the military unit accept method, in the code entry of the first client, the information of each military unit is saved $ thisunit-> accept ($ visitor );}}} // military class Army extends CompositeUnit {}// fleet class TroopCarrier extends CompositeUnit {}// visitor class abstract class ArmyVisitor {abstract function visit (Unit $ node ); // The business logic function visitArcher (Archer $ node) to be executed by the visitor {// In fact, I think this abstract class has an abstract method visit, in the original article, the following methods are used to call visit in a circle //...... $ this-> vis It ($ node);} function visitCavalry (Cavalry $ node ){//....... $ this-> visit ($ node);} function visitLaserCannonUnit (LaserCannonUnit $ node ){//...... $ this-> visit ($ node);} function visitTroopCarrierUnit (Cavalry $ node ){//...... $ this-> visit ($ node);} function visitArmy (Cavalry $ node ){//...... $ this-> visit ($ node) ;}// this visitor class is mainly used to obtain and save the information of the object to be visited. class TextDumpArmyVisitor extends ArmyVisitor {private $ t Ext = ""; function visit (Unit $ node) {$ ret = ""; $ pad = 4 * $ node-> getDpth (); $ ret. = sprintf ("% {$ pad} s", ""); $ ret. = get_class ($ node ). ":"; $ ret. = "bombard :". $ node-> bombardStrength (). "\ n"; $ this-> text. = $ ret;} function getText () {return $ this-> text ;}// visitor class used to collect taxes on each object, in client code 2, class TaxCollectionVisitor extends ArmyVisitor {private $ due = 0; private $ report = ""; function visit (Unit $ node ){ $ This-> levy ($ node, 1);} function visitArcher (Archer $ node) {// describes the method of the parent class, different taxes are collected for different units $ this-> levy ($ node, 2);} function visitCavalry (Cavalry $ node) {$ this-> levy ($ node, 3);} function visitTroopCarrierUnit (TroopCarrierUnit $ node) {$ this-> levy ($ node, 5);} private function levy (Unit $ unit, $ amount) {// main business logic $ this-> report. = "Tax levied ". get_class ($ unit); $ this-> report. = ": $ amount \ n"; $ this-> due + = $ Amount;} function getReport () {return $ this-> report;} function getTax () {return $ this-> due ;}} // client code 1 (get and output some information about each object) class UnitScript {static function joinExisting (Unit $ newUnit, Unit $ occupyingUnit) {$ comp; if (! Is_null ($ com = $ occupyingUnit-> getComposite () {$ comp-> addUnit ($ newUnit);} else {$ comp = new Army (); $ comp-> addUnit ($ occupyingUnit); $ com-> addUnit ($ newUnit);} return $ comp ;}$ main_army = new Army (); UnitScript :: joinExisting (new Archer (), $ main_army); UnitScript: joinExisting (new LaserCannonUnit (), $ main_army); UnitScript: joinExisting (new Cavalry (), $ main_army ); $ textdump = new TextDumpArmyVisitor (); $ Main_army-> accept ($ textdump); print $ textdump-> getText (); // client code 2 (tax on each object, and the total number of outputs collected) $ main_army = new Army (); UnitScript: joinExisting (new Archer (), $ main_army); UnitScript: joinExisting (new LaserCannonUnit (), $ main_army); UnitScript :: joinExisting (new Cavalry (), $ main_army); $ taxcollector = new TaxCollectionVisitor (); $ main_army-> accept ($ taxcollector); print $ taxcollector-> getTax (); // The above code is too lazy to test. Sorry! If you are interested, run debugging on your own!

The above discussion about the PHP object-oriented visitor mode + combination mode is all the content shared by the editor. I hope to give you a reference and support for the customer's house.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.