/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Pattern for interaction, del 2
Fra : Esben Mose Hansen


Dato : 24-08-02 23:13

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


 
 
Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408521
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste