Hej,
for laaang tid siden skrev jeg her i gruppen om der var et pattern for 
interaktion, hvor to objekter påvirker hinanden gensidigt afhængigt af 
klasserne. Dengang brugte jeg kollisioner imellem spilobjekter. Tag 
f.eks. tre spilobjekter (der nedarver fra GameObject):
public class Fireworks extends GameObject {}
public class Stone extends GameObject {}
public class WaterBalloon extends GameObject {}
Lad os for morskab opstille en lille tabel over hvad der skal ske når 
gameObject.collide(GameObject obj) kaldes:
      Fireworks   Stone      WaterBalloon
Fireworks 
bang! 
   shards      splash
Stone 
   shards      bounce      another splash
WaterBaloon 
splash 
   another splash   bounce
Ovenstående tabel illustrerer to ting a) vanen med at dokumentere på 
engelsk sidder dybt i mig og b) resultatet afhænger af begge objekters 
type. Og det jeg så spurgte om var: Hvur'n gør man så det. Jeg fik mange 
svar, og kunne ikke rigtigt lide nogen af dem :-/ Grundlæggende var der 
to slags:
1) Parametriser problemet (det problem jeg stillede var med lidt god 
vilje parametriserbart; ovenstående er med vilje gjort meget 
"uparametriserbart".
2) Brug en alle anden form for Runtime Identification. F.eks. kunne 
GameObjekt have en abstrakt funktion hvis kontrakt var at returnere 
navnet på den klassen. Det reducerer problemet til en switch-lig 
konstruktion:
public class GameObject {
   public void collide(GameObject obj) {
      int collisionType =
         collisionMatrix[getType()][obj.getType()];
         switch(collistionType) {
            case (bang):
               break;
            default:
               throw ...
         }
   }
}
Men jeg synes ikke den løsning er særlig elegant eller nem at 
vedligeholde. Reelt har man smidt OO over bord og gået tilbage til 
struktueret programmering. Så jeg var ikke rigtig glad.
Siden har jeg lært C++, og mens jeg gjorde det, har jeg læst nogle 
bøger. Blandt disse en bog der omhandler dette (More effective C++, af 
Scott Meyers). Han nævner flere løsninger (hvilket reelt betyder at der 
ikke er en rigtig god en):
1) Brug et andet sprog, der understøtter "multifunktioner", dvs. 
funktioner der er virtuelle med hensyn til mere end et objekt;
2) Implementer selv denne feature direkte (og ofre de fleste 
compiler-tjeks på alteret 

 ) (Kan man overhovedet det i Java?)
3) Accepter at du skal ændre i alle klasser hver gang du skal tilføje et 
nyt objekt til hierakiet, og gør som følger:
public abstract class GameObject {
   abstract public void collide(GameObject obj);
   abstract public void collide2(Fireworks obj);
   abstract public void collide2(Stone obj);
   abstract public void collide2(WaterBalloon obj);
}
public class Stone extrend GameObject {
   public void collide(GameObject obj) {
      obj.collide2(this);
   }
   public void collide2(FireWorks obj) {
      // shards
   }
   public void collide2(Stone obj) {
      // bounce
   }
   public void collide2(WaterBaloon obj) {
      // another splash
   }
   
}
Ligeså for de andre to klasser.
Fordelen er, at hvis man ligger en ny klasser til der extender 
GameObject burde compileren stort set lede en hele vejen gennem 
processen. Ydermere er der ingen exception i ovenstående: Hvis det 
compilere har vi husket det hele. De eneste uløste problemer er
1) Vi skal modiferer alle klasser hver gang.
2) alle collide2-metoderne burde egentligt være (samme) member i begge 
klasser, med de dertilkomne rettigheder. I ovenstående blive man nød til 
at offentligtgøre tilstrækkeligt meget af GameObjekternes interne 
stadier til at man kan implementerer Collide2-funktionerne via. de 
public interfaces. Men det sidste kan intet undtagen en udvidelse af 
sproget.)
Oh well. Tænkte bare at nogen måske kunne synes det var sjovt at se.
-- 
mvh. Esben
home.worldonline.dk/~mesben