All objects in Java are inherited from object objects. One of the advantages of this method is to make the data structure of some collection objects easy to manage. For example, you can put any type of objects into a vector. However, the problem is that if your set (connection) object not only stores a type of object, if you want to make some individualized operations on these objects, the first condition is to know the object type. Using instanceof seems to be a good method. In simple programs, you may do this: Public class elementa { // Some implementing } Public class elementb { // Some implementing } Public class elementc { // Some implementing } //...... Iterator = arraylist. iterator () While (iterator. hasnext ()){ If (O instanceof elementa) (Elementa) O. operationa (); Else if (O instanceof elementb) (Elementb) O. operationb (); Else if (O instanceof elementc) (Elementc) O. operationc (); Else System. Out. println ( "Sorry! I don't know who you are! " + O. tostring ()); //.... } //.... This is not impossible, but it will not be very scalable in the future. If you want to change the operation on each type of object at a time today, you must modify it in many places. From the perspective of the object itself, the object is in a house, and the object says, "Don't try to judge it out of the house. You don't know who I am, then you will come in and visit me. I will tell you who I am, so that you will know how to operate on me!" Use a program to implement the above description:
Public interface ielement { Public void accept (ivisitor visitor ); }
Public class elementa implements ielement { Public void accept (ivisitor visitor ){ Visitor. Visit (this ); } Public void operationa (){ System. Out. println ( "Do A's job... such-and-such ...."); } }
Public class elementb implements ielement { Public void accept (ivisitor visitor ){ Visitor. Visit (this ); } Public void operationb (){ System. Out. println ( "Do B's job... such-and-such ...."); } }
Public class elementc implements ielement { Public void accept (ivisitor visitor ){ Visitor. Visit (this ); } Public void operationc (){ System. Out. println ( "Do C's job... such-and-such ...."); } }
Public interface ivisitor { Public void visit (elementa element ); Public void visit (elementb element ); Public void visit (elementc element ); }
Public class visitora implements ivisitor { Public void visit (elementa element ){ Element. operationa (); } Public void visit (elementb element ){ Element. operationb (); } Public void visit (elementc element ){ Element. operationc (); } }
Public class main { Public static void main (string [] ARGs ){ // Know nothing about their type // After storing them into element array Ielement [] list = {New elementa (), New elementb (), New elementc ()}; Ivisitor visitor = new visitora (); For (INT I = 0; I <list. length; I ++) List. Accept (visitor ); } } Visitor access is based on overload. For every object implementing ielement, it accepts ivisitor to access it. In the accept () method, ivisitor uses the correct method to access ielement (obviously, this part can be achieved by different function names or overload) and performs corresponding operations on ielement in visit, if you want to replace the ielement operation today, you only need to replace the ivisitor type object, that is, this line: // Ivisitor visitor = new visitora (); // Replace an ivisitor to replace all the operations. // Do not modify multiple locations Ivisitor visitor = new visitorb (); For example, suppose visitora is just a lazy salesman. Today, visitorb, a very diligent salesman, will perform more operations on ielement after accessing ielement, to implement visitorb in a program, you only need to add a visitorb category:
Public class visitorb implements ivisitor { Public void visit (elementa element ){ System. Out. println ("visitorb is a hard worker ...."); Element. operationa (); System. Out. println ( "I want to do some extra work on ...."); } Public void visit (elementb element ){ System. Out. println ("visitorb is a hard worker ...."); Element. operationb (); System. Out. println ( "I want to do some extra work on B ...."); } Public void visit (elementc element ){ System. Out. println ("visitorb is a hard worker ...."); Element. operationc (); System. Out. println ( "I want to do some extra work on C ...."); } } Modify main to demonstrate:
Public class main { Public static void main (string [] ARGs ){ Ielement [] list = {New elementa (), New elementb (), New elementc ()}; System. Out. println ("visitora is coming ......."); Ivisitor visitora = new visitora (); For (INT I = 0; I <list. length; I ++) List. Accept (visitora ); System. Out. println ("\ nvisitorb is coming ......."); Ivisitor visitorb = new visitorb (); For (INT I = 0; I <list. length; I ++) List. Accept (visitorb ); } } In the example, system. Out. println (); is just a signal. It may also be a direct call to the ielement method. The UML structure diagram of the visitor mode is as follows: InJava WorldThere is an articleArticleThe reflection can be used to improve the flexibility when using the visitor mode. For more information, seeReflect on the Visitor Design Pattern. |