Translation tipatterns-complex interaction (complex interactions)

Source: Internet
Author: User

Complex interactions)

 

Multiple Dispatching)

Processing various types of interaction may make the program quite messy. For example, consider a system that parses and executes mathematical expressions. You need to support numbers + numbers, numbers × numbers, and so on. The number here is the base class of a series of numeric objects. However, if we only give a + B and we do not know the exact type of A or B, how can we make them interact correctly?

The answer to this question may be something you did not think of: Java can only perform single dispatching ). That is to say, if you operate on an unknown object of another type, Java can only enable the dynamic binding mechanism for one of these types. This does not solve the above problem, so you have to manually (write code) frame test type and generate your own dynamic binding behavior.

This solution is multiple dispatching ). Do not forget that polymorphism can only be implemented through member function calls. If you want to implement double dispatching, you must have two member function calls: the first call determines the first unknown type, the second call determines the second unknown type. For multi-allocation, you must have a method that can be called to determine all types. Generally, you can set configuration items to generate more than one dynamic member function call using a member function call, so that more than one type can be determined in this process. To do this, you need more than one multi-state method call: each dispatch requires one call. The (polymorphism) methods in the following example are compete () and eval (). They are all member functions of the same class (type. (In this case, there are only two distributions, that is, double distributions ). If you need to handle the interaction between different types of hierarchies, each system must implement a multi-state method call.

The following is an example of multiple distributions: (stone scissors)

//: Multipledispatch: paperscissorsrock. Java
// Demonstration of multiple dispatching.
Package multipledispatch;
Import java. util .*;
Import JUnit. Framework .*;
 
// An enumeration type:
Class outcome {
Private string name;
Private outcome (string name) {This. Name = Name ;}
Public final static outcome
Win = new outcome ("wins "),
Lose = new outcome ("loses "),
Draw = new outcome ("draws ");
Public String tostring () {return name ;}
}
 
Interface item {
Outcome compete (item it );
Outcome eval (paper P );
Outcome eval (scissors S );
Outcome eval (rock R );
}
 
Class paper implements item {
Public outcome compete (item it) {return it. eval (this );}
Public outcome eval (paper p) {return outcome. Draw ;}
Public outcome eval (scissors s) {return outcome. Win ;}
Public outcome eval (rock R) {return outcome. Lose ;}
Public String tostring () {return "paper ";}
}
 
Class scissors implements item {
Public outcome compete (item it) {return it. eval (this );}
Public outcome eval (paper p) {return outcome. Lose ;}
Public outcome eval (scissors s) {return outcome. Draw ;}
Public outcome eval (rock R) {return outcome. Win ;}
Public String tostring () {return "Scissors ";}
}
 
Class rock implements item {
Public outcome compete (item it) {return it. eval (this );}
Public outcome eval (paper p) {return outcome. Win ;}
Public outcome eval (scissors s) {return outcome. Lose ;}
Public outcome eval (rock R) {return outcome. Draw ;}
Public String tostring () {return "rock ";}
}
 
Class itemgenerator {
Private Static random Rand = new random ();
Public static item newitem (){
Switch (RAND. nextint (3 )){
Default:
Case 0: return new scissors ();
Case 1: return new paper ();
Case 2: return new rock ();
}
}
}
 
Class compete {
Public static void match (item A, item B ){
System. Out. println (
A + "" + A. compete (B) + "vs." + B );
}
}
 
Public class paperscissorsrock extends testcase {
Static int size = 20;
Public void test (){
For (INT I = 0; I <size; I ++)
Compete. Match (itemgenerator. newitem (),
Itemgenerator. newitem ());
}
Public static void main (string ARGs []) {
JUnit. textui. testrunner. Run (paperscissorsrock. Class );
}
}///:~
 
 
 

Visitor (visitor), a type of multi-allocation

Assume that you have an earlier class hierachy. These classes are fixed and cannot be changed. They may be bought from a third party, so you cannot change this hierarchy. However, you may want to add a new multi-state method to this class hierarchy. Normally, you must add new things to the base class interface. So the problem arises: You need to add a new method to the base class, but you do not have to act on the base class. What should I do?

The design pattern for solving such problems is called "visitor" (the last one mentioned in design pattern). It is built on the dual-path allocation mechanism in the previous section.

The visitor mode allows you to expand the original type of interfaces by creating another Independent Visitor class hierarchy, so as to simulate (Virtualize) the original operations on the original type. The original type of object is simply "accept" the visitor, and then calls the member function dynamically bound by the visitor.

//: Visitor: beeandflowers. Java
// Demonstration of "visitor" pattern.
Package visitor;
Import java. util .*;
Import JUnit. Framework .*;
 
Interface visitor {
Void visit (gladiolus G );
Void visit (runuculus R );
Void visit (Chrysanthemum C );
}
 
// The flower Hierarchy cannot be changed:
Interface flower {
Void accept (visitor V );
}
 
Class gladiolus implements flower {
Public void accept (visitor v) {v. Visit (this );}
}
 
Class runuculus implements flower {
Public void accept (visitor v) {v. Visit (this );}
}
 
Class chrysanthemum implements flower {
Public void accept (visitor v) {v. Visit (this );}
}
 
// Add the ability to produce a string:
Class stringval implements visitor {
String S;
Public String tostring () {return s ;}
Public void visit (gladiolus g ){
S = "gladiolus ";
}
Public void visit (runuculus R ){
S = "runuculus ";
}
Public void visit (Chrysanthemum c ){
S = "Chrysanthemum ";
}
}
 
// Add the ability to do "Bee" activities:
Class bee implements visitor {
Public void visit (gladiolus g ){
System. Out. println ("Bee and gladiolus ");
}
Public void visit (runuculus R ){
System. Out. println ("Bee and runuculus ");
}
Public void visit (Chrysanthemum c ){
System. Out. println ("Bee and Chrysanthemum ");
}
}
 
Class flowergenerator {
Private Static random Rand = new random ();
Public static flower newflower (){
Switch (RAND. nextint (3 )){
Default:
Case 0: return New gladiolus ();
Case 1: return New runuculus ();
Case 2: return New chrysanthemum ();
}
}
}
 
Public class beeandflowers extends testcase {
List flowers = new arraylist ();
Public beeandflowers (){
For (INT I = 0; I <10; I ++)
Flowers. Add (flowergenerator. newflower ());
}
Public void test (){
// It's almost as if I had a function
// Produce a flower string representation:
Stringval sval = new stringval ();
Iterator it = flowers. iterator ();
While (it. hasnext ()){
(Flower) it. Next (). Accept (sval );
System. Out. println (sval );
}
// Perform "Bee" operation on all flowers:
Bee = new Bee ();
It = flowers. iterator ();
While (it. hasnext ())
(Flower) it. Next (). Accept (BEE );
}
Public static void main (string ARGs []) {
JUnit. textui. testrunner. Run (beeandflowers. Class );
}
}///:~

 

Exercise
1. Write a business modeling system that includes three types of Inhabitant: GNOME (representing engineers), Genie (representing market personnel), and giant (representing managers ). Write a project class, create different inhabitants, and let them interact, you must use multiple distributions.


2. rewrite exercise 1 to make their interaction more detailed. Each inhabitant can use getweapon () to generate a random weapon: the gnome uses jargon or play, the genie uses inventfeature or sellimaginaryproduct, And the giants use edioct and schedule. You must decide which weapon to win in each interaction (like paperscissorsrock. Java ). Add a battle () member function to the project class. It accepts two types of inhabitants (as parameters) to combine them. Add a meeting () member function to the project class, create a group of gnomiters, Genie, and giants, and let the groups fight until the last group wins.

3. Rewrite paperscissorsrock. Java and use the table query method instead of the dual-path Assignment Method. The simplest way is to write a map with a value of maps and use the class name of each object as the map key. Then, use the following method to search:
(MAP) map. Get (o1.getclass (). Get (o2.getclass ())
Using this method, you can easily configure the system with the center of gravity. When will this method be more suitable than hard-coded dynamic distribution? Can you use the table search method to write a simple syntax system for dynamic allocation?


4. Redo Exercise 2 using the table search method of Exercise 3.

 

 

Directory

 

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.