Best Practice zu vielen konstanten Objekten?

Hutmacher

Bekanntes Mitglied
Hallo!
Zerbreche mir gerade darüber den Kopf, wie ich Folgendes designtechnisch am besten umsetzen kann:
Um das Ganzen mal zu abstrahieren und aus dem konkreten, größeren Kontext zu reißen, habe ich das Ganze mal als ein einfaches Beispiel formuliert:
In einem Spiel habe ich einen Helden, der Items tragen kann. Es gibt schon einige vorkonfigurierte Items, aber es sollen auch Items erst zur Laufzeit erstellt werden. Items werden nicht nur vom Spieler, sondern auch von anderen Klassen benutzt.

Dies ist die Klasse Item:
Java:
public class Item
{
	private String name;
	private double weight;
	
	public Item(String name, double weight)
	{
		this.name = name;
		this.weight = weight;
	}
	
	public String getName()
	{
		return name;
	}
	
	public double getWeight()
	{
		return weight;
	}
}

Für die fixen Items könnte ich nun eine Klasse erstellen, die viele Konstanten hält, also z.B.:
Java:
class Items
{
   public static final Item POTION = new Item("Potion", 5),
                            SWORD = new Item("Sword", 44); //und noch mehr   
}

Nun kann ich sowohl mit
Code:
new Item("Thing", 44)
neue Items erstellen, als auch mit
Code:
Items.POTION
auf bestehende zugreifen.

Dies wäre der erste Ansatz, der mir einfiel, aber seit Java 1.5 gibt es ja Enums, die man, so weit ich weiß, möglichst anstatt von vielen Konstanten verwenden sollte.

Angenommen, ich schreibe nun Item als Enum:
Java:
public enum Item
{	
	POTION("Potion", 4),
	SWORD("Sword", 44);
	
	private String name;
	private double weight;
	
	Item(String name, double gewicht)
	{
		this.name = name;
		this.weight = gewicht;
	}
	
	public String getName()
	{
		return name;
	}
	
	public double getWeight()
	{
		return weight;
	}

}

Nun kann ich zwar immer noch bequem auf die existierenden Items zugreifen mit
Code:
Item.POTION
, aber ich kann keine neuen Gegenstände mehr zur Laufzeit erstellen.


Gibt es eine Möglichkeit, mein obiges Anliegen mit enums zu bewältigen oder muss ich bei den Konstanten bleiben?
 

Michael...

Top Contributor
In Java gibt es keine Konstanten ;-)
Sollen diese Items denn tatsächlich statisch sein? Können diese sich nicht Heldenspezifisch verändern/verhalten. z.B. eine Wasserflasche die mit der Zeit immer leerer wird?

Wieso willst Du unbedingt Enums?

Ich könnte mir vorstellen, dass für so einen Fall auch eine Factory interessant sein könnte. Also einfach eine ItemFactory die diese StandardItems erzeugt und bereitstellt.
 
T

tuxedo

Gast
Versteh noch nicht wieso du "fixen Items" auch als "fixe Objekte" haben willst. Würde diese gar nicht im Code definieren, sondern in XML, Datenbank, Property-File oder sonstwie auslagern und dann beim Programmstart oder bei Bedarf einlesen und das entsprechende Objekt ins Leben rufen.

Wenn du Gewicht und Name hard-codierst, dann sind Anpassungen z.B. wegen anzupassendem Balancing des Spiels aufwendiger (es muss ein build laufen).
 

Volvagia

Top Contributor
Warum brauchst du überhaupt Konstanten?
Könntest es ja auslagern.
z. B. so:

//ID, Name, Type, Gewicht
0;Sword;0;44
1;Trank;3;5

Wobei ich persönlich seit kurzen XML vorziehe, aber der Code dafür ist etwas aufwendiger als ein einfacher BufferedReader etc.

Das lädst du bei Spielbeginn, z. B. in eine Klasse ItemTemplate. Vielleicht noch eine Oberklasse ItemManager, der aus der ID dann Items generiert.
Dann brauchst du immer nur die ID um ein Item zu bekommen. Das erleichtert das Verwalten und minimiert imho auch die Abhängigkeiten.
Falls du vorhast auch soetwas wie zufällige Items zu erzeugen könnte der Verwalter ja neue Einträge mit neuen IDs vornehmen und sie abspeichern.

In Java gibt es keine Konstanten ;-)
:eek:
 

Momolin

Aktives Mitglied
Hallo,

ich finde Deinen Vorschlag mit den vordefinierten Konstanten am besten und würde ihn um finale Attribute erweitern und auch die Klasse selber final machen:
Java:
public final class Item {

	public static final Item POTION = new Item("Potion", 5);
	public static final Item SWORD = new Item("Sword", 44); // und noch mehr

	private final String name;
	private final double weight;

	public Item(String name, double weight) {
		this.name = name;
		this.weight = weight;
	}
}

ich finde das drückt am besten aus, was Du haben willst. Die Klasse Item ist dann mit der String-Klasse vergleichbar. Auch Joshua Bloch beschreibt das in seinem Buch Effective Java unter dem Item 15: Minimize mutability so ähnlich.

Grüße
 

D4rkscr43m

Bekanntes Mitglied
Generell würde ich bei sowas immer von Enums weg zu Interfaces gehen. Vorallem weil bestimmte Items andere Auswirkungen haben, dann kann z.B. ein Interface Item ganz hilfreich sein, da du dann alle Items stapeln kannst aber gleichzeitig deiner Potion einen Effekt geben (Anwender Energie + 1) und deinem Schwert einen anderen (Ziel Energie - 1) etc.
Mit diesem Design hast du außerdem den Vorteil, dass du beim Erweitern z.B. eine neue Waffe einfach hinzufügen kannst indem du dann von Sword ableitest und z.B. den Schaden erhöhst.
 

Hutmacher

Bekanntes Mitglied
Ihr habt natürlich alle recht, es wäre viel sinnvoller, so etwas in einer Datei auszulagern :) Hatte noch im Kopf, dass das mit enums auch möglich wäre, aber scheint nicht so.

Michael... hat gesagt.:
In Java gibt es keine Konstanten ;)

Den Satz musst du mir wohl erklären :p Oder meinst du wegen des unbenutzen const-Keywords?
 
T

Tomate_Salat

Gast
Den Satz musst du mir wohl erklären :p Oder meinst du wegen des unbenutzen const-Keywords?

Es gibt keine Konstanten in Java. Es gibt nur das final. Aber das lässt sich mittels JNI oder Reflection sehr einfach umgehen. Es ist zwar schwieriger/mehr Aufwand den Wert zu ändern, aber eine Garantie darauf, dass er konstant bleibt, hast du eben nicht.
 
B

bygones

Gast
man kann schon meiner ansicht nach von Konstanten reden, alles andere verwirrt eher. Dass man mit mehr oder weniger ueblen Tricks das umgehen kann ist eine andere Sache. Das selbe gilt auch fuer private, will man nun immer sagen, dass private nicht wirklich private ist ?

Ich halte auch die hardocodierte Variante der Items fuer nicht gut, leg sie als xml, json oder yaml oder was auch immer ab und lade sie beim programmstart.

Von enums wuerde ich hier komplett abraten, da du ja wie du sagst, auch neue items erstellen willst im Spiel. Das ist mit enums nicht moeglich.
 
S

Spacerat

Gast
Man könnte das mit Interfaces lösen.
Java:
public interface Item {
  String getName();
  int getWeight();
}

public interface FixedItem<T extends Enum<T>> extends Item {
}

public enum FixedItemSetOne implements FixedItem<FixedItemSetOne> {
  ... define your first set of fixed items
}

public enum FixedItemSetTwo implements FixedItem<FixedItemSetTwo> {
  ... define your second set of fixed items
}

public class UserItemSetOne implements Item {
  ... implement interface and define item constants for user set one
}

public class UserItemSetTwo implements Item {
  ... implement interface and define item constants for user set two
}

...aso
...schon kannst du mit Items um dich schmeissen.
BTW.: Auf 'ne Diskussion, ob es in Java "constants" gibt oder nicht, lasse ich mich nicht ein, ist mir zu blöd'. ;)
[EDIT]Was dem Ganzen im übrigen noch fehlt ist eine einmalige ItemID und zwar so einmalig, das man es nicht schafft, sich selber Items mit gleichem Namen und Gewicht zu erstellen. Mit Enums hätte man da kein Problem, weil sich dort equals (prüft auf Identität) und hashCode eh' nicht mehr überschreiben lässt.[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

faetzminator

Gesperrter Benutzer
Den Satz musst du mir wohl erklären :p Oder meinst du wegen des unbenutzen const-Keywords?

Mit [c]final[/c] kann man bekanntlich diese Variable für immer (siehe Ausnahmen) auf das gleiche Objekt zeigen lassen.
Trotzdem können innerhalb vom Objekt Daten nach belieben verändert werden - es sei denn, es ist eine primitive Veriable oder ein immutable Objekt. Deshalb gibt's keine Konstanten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Best Practice überprüfen von Übergabeparametern Allgemeine Java-Themen 17
S best practice: Einordnung Enitity und Datenklasse Allgemeine Java-Themen 11
temi best practice: Parameter überprüfen, wo? Allgemeine Java-Themen 9
Airwolf89 JUnit: Vorschläge/ Best Practice Allgemeine Java-Themen 7
M Best Practice: Daten aufnehmen-speichern-bereitstellen Allgemeine Java-Themen 8
F best practice Allgemeine Java-Themen 5
J Input/Output Dateien bearbeiten - "Best Practice" Allgemeine Java-Themen 3
R Statische Klasse: Best practice mit flags (2) Allgemeine Java-Themen 3
musiKk Best Practice für kleine Variationen in gegebenen Modellklassen Allgemeine Java-Themen 11
J Best Practice für implementierung von equals(...) Allgemeine Java-Themen 7
Daniel_L Best Practice zum Löschen von Log-Files? Allgemeine Java-Themen 8
Ameise03 Best&Worst Case bei Insertionsort Allgemeine Java-Themen 10
S Best Practices CopyConstrutor mit ArrayList Allgemeine Java-Themen 1
F Error Logging - best practices? Allgemeine Java-Themen 3
M Best Practices für Undo/Redo Allgemeine Java-Themen 16
G Best Practices Software-Engineering‏ Allgemeine Java-Themen 3
G Best Practices Allgemeine Java-Themen 10
M Best Practices Exception Handling für eigene library Allgemeine Java-Themen 8
S best practise Allgemeine Java-Themen 6
S Array: Anzahl Elemente mit best. Wert zählen Allgemeine Java-Themen 4
M Best Match / Best Fit auf Strings Allgemeine Java-Themen 9
D Verwaltung von sehr vielen Objekten Allgemeine Java-Themen 12
M Klassen in vielen Jars ermitteln Allgemeine Java-Themen 2
C Darstellung der Liste bei vielen Daten extrem langsam Allgemeine Java-Themen 11
T Stresstest mit seeehr vielen Clients? Allgemeine Java-Themen 21
S Aufruf in Konsole mit beliebig vielen Argumenten? Allgemeine Java-Themen 18
P Vector in vielen Klassen Allgemeine Java-Themen 21
M Problem beim laden von vielen Bildern Allgemeine Java-Themen 16
G Panel mit vielen Komponenten verbraucht viel Speicher Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben