public Gegner neuerGegner(int id) {
switch(id) {
case 1: return new Kaefer();
case 2: return new Zombie();
usw.
}
}
public enum GegnerProvider {
KAEFER_PV {
Gegner createGegner() {
System.out.printf("Creating Enemy with %s%n",name());
return new Gegner() {
};
}
}, ZOMBIE_PV {
Gegner createGegner() {
System.out.printf("Creating Enemy with %s%n",name());
return new Gegner() {
};
}
}, ALIEN_PV {
Gegner createGegner() {
System.out.printf("Creating Enemy with %s%n",name());
return new Gegner() {
};
}
};
abstract Gegner createGegner();
}
public class Game {
public void play(){
Gegner kaefer = GegnerProvider.values()[0].createGegner();
Gegner zombie = GegnerProvider.ZOMBIE_PV.createGegner();
Gegner alien = GegnerProvider.valueOf("ALIEN_PV").createGegner();
}
public static void main(String[] args){
new Game().play();
}
}
GegnerFactory dieBrueterei = {new ZombieFactory(), new AlienFactory()};
dieBrueterei[id].createGegner();
package gegner;
public interface GegnerFactory {
Gegner createGegner();
}
package gegner;
public class Gegner {
private String name;
private int energy;
private int hitPoints;
public Gegner(String name, int energy, int hitPoints) {
super();
this.name = name;
this.energy = energy;
this.hitPoints = hitPoints;
}
@Override
public String toString() {
return "Gegner [name=" + name + ", energy=" + energy + ", hitPoints=" + hitPoints + "]";
}
}
package gegner;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class GegnerProvider {
Map<String, GegnerFactory> gegnerFactories = new HashMap<String, GegnerFactory>();
public GegnerProvider(){
gegnerFactories.put("ZOMBIE", new GegnerFactory() {
@Override
public Gegner createGegner() {
return new Gegner("Zombie", 10, 1);
}
});
gegnerFactories.put("ZOMBIE_100", new GegnerFactory() {
@Override
public Gegner createGegner() {
return new Gegner("Zombie 100", 100, 5);
}
});
gegnerFactories.put("ALIEN", new GegnerFactory() {
@Override
public Gegner createGegner() {
return new Gegner("Alien", 1000, 10);
}
});
}
public Gegner createGegner(String id){
GegnerFactory factory = gegnerFactories.get(id);
if(factory == null){
throw new IllegalArgumentException("No Factory with ID "+id);
}
return factory.createGegner();
}
public Set<String> getPossibleIds(){
return gegnerFactories.keySet();
}
public void addFactory(String id, GegnerFactory factory){
if(gegnerFactories.get(id) != null){
throw new IllegalArgumentException("Factory with "+id+" allready exists");
}
gegnerFactories.put(id, factory);
}
}
package gegner;
public class Test {
public static void main(String[] args) {
GegnerProvider provider = new GegnerProvider();
System.out.println(provider.createGegner("ZOMBIE"));
System.out.println(provider.createGegner("ALIEN"));
// habe später die Möglichkeit ohne meine Kern Anwendung zu verändern,
// neue Typen hinzuzufügen zb über irgend einen Plugin Mechanismus
provider.addFactory("NEW_ENEMY", new GegnerFactory() {
@Override
public Gegner createGegner() {
return new Gegner("neuer Gegner", 1, 1);
}
});
System.out.println(provider.createGegner("NEW_ENEMY"));
}
}
aber ob man es schaft den vorteil zu messen das bezweifle ich...
Kann mir jemand sagen was schneller ist? Ein verschachteltes if [...]
oder ein switch
interface GameObjectType<E extends Enum<E>> {
GameObject create();
}
enum TypeSetA implements GameObjectType<TypeSetA> {
BUG(Bug.class),
ZOMBIE(Zombie.class),
;
private final Class<? extends GameObject> clazz;
private TypeSetA(Class<? extends GameObject> clazz) {
this.clazz = clazz;
}
@Override
public GameObject create() {
try {
return clazz.newInstance();
} catch(ReflectiveOperationException e) {
return null;
}
}
}
enum TypeSetB implements GameObjectType<TypeSetB> {
CAT(Cat.class),
DOG(Dog.class),
;
private final Class<? extends GameObject> clazz;
private TypeSetB(Class<? extends GameObject> clazz) {
this.clazz = clazz;
}
@Override
public GameObject create() {
try {
return clazz.newInstance();
} catch(ReflectiveOperationException e) {
return null;
}
}
}
class GameObject {
}
class Zombie extends GameObject {
}
class Bug extends GameObject {
}
class Cat extends GameObject {
}
class Dog extends GameObject {
}
Switch und If sind ein und derselbe Code nur anderst aufgeschrieben.
Switch wurde eingeführt um die Daten anderst darstellen zu können und dem Programmierer unter umständen das lesen des Codes zu erleichtern.
Stimmt, da ist was wahres dran. Switch funktioniert - im Hintergrund - eigentlich nur mit integralen Werten, vergleichbar mit Sprungtabellen in Assembler (Switch funktioniert deswegen auch nur mit Konstanten). Und jetzt wo du Strings in Switch erwähnst, frage ich mich, ob das der Grund ist, warum nun jeder nicht internalisierte String sein eigenes Chararray hat, weswegen es die Member offset und count auch nicht mehr gibt und für Switch nun die Startadresse dieses Arrays verwendet wird. Ferner frage ich mich, wieso hat man dann nur Strings ermöglicht und nicht auch noch gleich andere Immutables (ausser die Wrapperklassen). In Assembler funktionieren Sprungtabellen mit jeder Art von Objekt, aber das ist erstens eh' 'ne ganz andere Liga und in Java immerhin emulierbar.[/OT]Das stimmt so nicht, da wird auch anderer Bytecode erzeugt, genau deswegen gingen ganz lange keine Strings in Switch-Blöcken.
Kann mir jemand sagen was schneller ist? Ein verschachteltes if in der Form:
Java:if(a < 1024){ if(a < 512) { if(a < 256) { usw.... } } }
oder ein switch mit 1024 verschiedenen cases.
Also ein 10 mal verschachteltes if oder ein switch mit 1024 cases?