MVC: Kommunikation der Modellteile

editOr

Mitglied
Hallo Java-Community

Immer wieder passiert es mir, dass ich zwar eine lauffähige Version hinbekomme, der Code aber sehr unschön ist. Ich habe mir deshalb vorgenommen, etwas mehr auf das Design zu achten. Ich habe dabei oft das Problem, dass ich nicht genau weiss, wo ich verschiedenste Codestücke unterbringen soll.

Nachfolgendes Beipspiel zeigt mein Problem glaube ich ziemlich gut. Ich habe versucht, ein Snake-Spiel mit Hilfe eines MVC-Patterns zu bauen. Soweit klappt alles bestens. Ich habe dazu vereinfacht folgende Modell-Klassen.

SnakeModel: (Beschreibt die Lage und Richtung der Schlange)
- Vector<FieldPoint> coveredFieldPoints
- int Direction

WallModel (Die Lage der Wände)
- private Vector<FieldPoint> wallPieces

FruitModel (beschreibt die Lage aller einzusammelnden "Früchte")
- Vector<Fruit> fruits

GameStatus (beeinhaltet Informationen zum Spielstand)
- int points
- boolean gameOver

Ferner:
FieldPoint
- int x
- int y

Fruit
- int value
- FieldPoint location

Soweit alles gut. Gehen wir davon aus, dass das Spiel läuft und die Lage der Schlange ständig angepasst wird (coveredFieldPoints). Die Frage die sich mir nun stellt ist, wo bringe ich die Logik, resp. Interaktion der Modelle zusammen.

Beipielsweise muss ich bei jedem Schritt der Schlange prüfen, ob sie in eine Wand oder in in eigenen Schwanz gefahren ist --> GameOver.

Ich habe dies als Methode "checkGameOverStatus" in der Klasse GameStatus untergebracht. Dazu übergebe ich der Methode das SnakeModel und das WallModel. Dies finde ich prinzipiell noch ok, da ich ja eine Eigenschaft der Klasse GameStatus, namentlich das Feld gameOver setzen will. Oder gehört das auch schon nicht hierhin?

Anders sieht es aber aus, wenn ich den Spielstand (die Punkte) updaten möchte. Wiederum erstelle ich eine Methode "updatePoints" in der Klasse Gamestatus, der ich das SnakeModel und das FruitModel übergebe. Ich prüfe dann, ob die Schlange gerade eine Frucht gefressen hat und erhöhe Allenfalls den Spielstand. Auch hier bin ich der Meinung, dass man das hier machen kann, da ein Feld von Gamestatus betroffen ist.

Wird nun aber eine Frucht "gefressen" muss diese Frucht natürlich auch aus dem FruitModel entfernt werden und eine neue Frucht gesetzt werden. Heute habe ich das direkt in der "updatePoints" der Klasse GameStatus integriert. Dies aber lediglich darum, da ich hier um die Punkte zu aktualisieren ebenfalls prüfen muss, ob eine Frucht gefressen wurde. Hingehören tut es hier aber eigentlich nicht, oder? Schliesslich besagt der Name der Methode ja updatePoints und wenn ich darin das FruitModel anpasse passiert etwas, was man so nicht erwarten würde.

Meine Frage nun, wo gehört die Anpassung des FruitModels denn hin? Ihr seht, ich habe allgemein Probleme die Interaktion verschiedenen Modelle an geeigneter Stelle zu verküpfen und wäre froh um Inputs.

Vielen Dank
edit0r
 

Marco13

Top Contributor
DAS Silver Bullet gibt es nicht.

Und ich finde auch wichtig zu erwähnen, dass MVC nicht primär für Spiele gedacht ist (als das entwickelt wurde, gab es kaum mehr als Pong :D). Und es gibt Spiele, wo es "einfach nicht passt".

In diesem Fall könnte man das Spiel sicher viel einfacher schreiben, wenn man es nicht nach MVC aufbauen würde. Hast du wirklich für alle Modellklassen Interfaces definiert und Default-Implementierungen und Events über die die View benachrichtigt wird? Wenn es darum geht, ein Snake-Spiel zu schreiben, wäre das nur bedingt nutzbringend. Wenn es darum geht zu üben, spricht da nichts dagegen.

Aber .... nebenbei: Nur weil man seine Klassen "*Model" nennt und/oder MVC umsetzt, wird das Design nicht automatisch "gut" ;) Der wichtigste Grundgedanke am MVC ist, die View und das Modell zu trennen. Wenn man das umsetzt, spielen bestimmte Details und Ausprägungen nicht unbedingt eine so große Rolle. Ich denke auch dass es in diesem/so einem Fall eine Art "Orchestrierung" geben könnte, die den Spielablauf steuert. (Um dabei zu bleiben könnte man das vielleicht den "Controller" nennen, aber ... naja. )

Oder an einem Beispiel:
Beipielsweise muss ich bei jedem Schritt der Schlange prüfen, ob sie in eine Wand oder in in eigenen Schwanz gefahren ist --> GameOver.

Ich habe dies als Methode "checkGameOverStatus" in der Klasse GameStatus untergebracht. Dazu übergebe ich der Methode das SnakeModel und das WallModel.
Man KÖNNTE, wenn man das in das Modell-Schema pressen wollte, auch sagen: Die Schlange hat eine Methode wie
Java:
void move()
{
    ...
    if (hitSomething())
    {
        fireHitEventToAllListeners(new SnakeHitSomethingEvent(this, theHitThing));
    }
    if (hasEatenFruit())
    {
        fireEatEventToAllListeners(new SnakeAteSomethingEvent(this, theEatenFruit));
    }
}
und wer sich dafür interessiert, ob die Schlange irgendwo dagegen fährt, oder ob die Schlange eine Frucht frißt, muss sich eben als Listener registrieren. Nochmal: Wie sinnvoll das ist, kann man in Frage stellen, aber "so was" wäre "MVC-näher"....

Aber warte mal ab, was andere noch dazu sagen. Ich bewege mich da auch immer auf dem dünnen Eis hochgradiger Subjektivität ;)
 

kaetzacoatl

Bekanntes Mitglied
Ich würd alles in eine Klasse mache!
Java:
public class Snake {
	
	ArrayList<Point> snake = new ArrayList<Point>();
	Point fruit;
	int fruitvalue;
	ArrayList<Point> wall = new ArrayList<Point>();
	boolean gameover;
	
	public void update(){		
		for(int i = 0;i < snake.size();i++){
			for(int a = 0;a < snake.size();a++){
				if(a != i && snake.get(i).x == snake.get(a).x && snake.get(i).y == snake.get(a).y){
					gameover = true;
				}
			}
			for(int a = 0;a < wall.size();a++){
				if(snake.get(i).x == wall.get(a).x && snake.get(i).y == wall.get(a).y){
					gameover = true;
				}
			}
			if(snake.get(i).x == fruit.x && snake.get(i).y == fruit.y);
		}
	}
	
	public void update(Point p){
		snake.add(0, p);
		snake.remove(snake.size()-1);
		if(p.x == fruit.x && p.y == fruit.y);
		for(int i = 0;i < snake.size();i++){
			if(snake.get(i).x == p.x && snake.get(i).y ==p.y);
		}
	}

}
:D
nur ein paar inspirationen
 

lilith2k3

Mitglied
Und ich finde auch wichtig zu erwähnen, dass MVC nicht primär für Spiele gedacht ist
Quatsch.

Code:
Nachfolgendes Beipspiel zeigt mein Problem glaube ich ziemlich gut. Ich habe versucht, ein Snake-Spiel mit Hilfe eines MVC-Patterns zu bauen. Soweit klappt alles bestens. Ich habe dazu vereinfacht folgende Modell-Klassen. 

SnakeModel: (Beschreibt die Lage und Richtung der Schlange)
- Vector<FieldPoint> coveredFieldPoints
- int Direction

WallModel (Die Lage der Wände)
- private Vector<FieldPoint> wallPieces

FruitModel (beschreibt die Lage aller einzusammelnden "Früchte")
- Vector<Fruit> fruits 

GameStatus (beeinhaltet Informationen zum Spielstand)
- int points
- boolean gameOver

Ferner:
FieldPoint
- int x
- int y

Fruit
- int value
- FieldPoint location

Das ist doch schon einmal ein Ansatz.
Du hast für alle "Objekte" des Spiels jeweils eigene Modelle geschaffen. Das ist ein guter Ausgangspunkt.
Um bei'm MVC oder besser noch MVVM (MVP oder wasauchimmer) zu bleiben musst Du zum einen noch die Controler definieren.
Du benötigst zumindest einen Controller, der sich um die eigentliche Spielmechanik kümmert, der dann die Modelle aktualisiert, berechnungen vornimmt und der View, bzw. bei MVVM dem Viewmodel Nachricht über Änderungen mitteilt.

Gerade bei Spielen findet die MVC-Aufteilung Anwendung.
 

Marco13

Top Contributor
Irgendwie habe ich gerade das Gefühl, dass du OOP und MVC verwechselst. Bekräftigt wird das dadurch, dass du meinst, es würde gerade in Spielen eingesetzt, und dass du anhand der "Klassen"beschreibungen meinst, das entsrpäche schon dem MVC, und dass du zu ignorieren scheinst, dass die Beschreibung im ersten Post darauf hindeutet, dass keine allgemeinen (entkoppelnden) Benachrichtigungsmechanismen vorhanden sind. Aber bestätigt natürlich nicht, d.h. vielleicht täuscht das auch.
 

lilith2k3

Mitglied
Irgendwie habe ich gerade das Gefühl, dass du OOP und MVC verwechselst. Bekräftigt wird das dadurch, dass du meinst, es würde gerade in Spielen eingesetzt, und dass du anhand der "Klassen"beschreibungen meinst, das entsrpäche schon dem MVC, und dass du zu ignorieren scheinst, dass die Beschreibung im ersten Post darauf hindeutet, dass keine allgemeinen (entkoppelnden) Benachrichtigungsmechanismen vorhanden sind. Aber bestätigt natürlich nicht, d.h. vielleicht täuscht das auch.

Irgendwie habe ich das Gefühl, dass Du entweder nicht weißt, was MVC beinhaltet, oder mich nicht verstanden hast.

Es geht darum, dass die vorkommenden "Entitäten" eines Spiels im Modell abgelegt werden, man die Spielmechanik als Controler formuliert und die View letztlich das ist, was man auf dem Bildschirm sieht.

Es geht im Allgemeinen um "separation of concerns" und es hat in meinen Augen keinen Sinn, wenn eine Spielfigur selbst wissen muss, ob sie gegen eine Wand gelaufen ist oder nicht. Das ist Aufgabe der Game-Engine. Ebenso muss eine Spielfigur nichts von Ihrer graphischen Repräsentation wissen. Darum kümmert sich letztlich ebenfalls die Game-Engine in Kollaboration mit der View.

So funktioniert MVC: Trennung von Modell, Darstellung und "Geschäftslogik".
 

Marco13

Top Contributor
Nun, das meinte ich mit dem fehlenden Silver Bullet, und der hochgradigen Subjektivität. Wenn jemand meint, dass MVC noch MVC ist, wenn das Modell nicht in irgendeinem Sinn observable ist, und die View nicht in irgendeinem Sinn Observer des Modells, dann widersrpicht das meiner Auffassung davon (und ... der Auffassung von jedem, der bisher etwas über MVC geschrieben hat, was ich gelesen haben - außer dir). Separation of Concerns impliziert nicht, dass man MVC verwendet (umgehehrt aber schon).
 

editOr

Mitglied
Vielen Dank für eure Inputs
Wenn es darum geht, ein Snake-Spiel zu schreiben, wäre das nur bedingt nutzbringend. Wenn es darum geht zu üben, spricht da nichts dagegen.
Genau, eigentlich ist es nicht so wichtig, ob das jetzt Snake ist, oder ein Taschenrechner oder was auch immer. Mir geht es mehr darum das MVC-Konzept einmal an einem (idealerweise) nicht mehr ganz trivialen Beispiel (nicht nur je 1 Klasse für Model, View und Controller) für welche es genügend Tutorials gibt. Ich habe mir deshalb Snake ausgesucht, da einfach aber nicht mehr trivial.

Den Vorschlag von kaetzacoatl, alles in eine Klasse zu packen wäre wohl möglich, möchte ich aber eben gezielt nicht, da mich eben gerade eben die Probleme die entstehen wenn das nicht der Fall ist interessieren.

So funktioniert MVC: Trennung von Modell, Darstellung und "Geschäftslogik".
Ich glaube mein Problem "Wo gehört was hin?" hat genau damit zu tun. Du setzt hier den Controller mit der Business-Logik gleich, das ist meiner Meinung nach gerade nicht der Fall. Nach etwas Googlen zeigt sich, dass das Gros aller Beiträge die Geschäftslogik im Modell sehen.

Für mich heisst das, das Modell stellt alle Eigenschaften aber auch nötigen Manipulationen und Berechnungen durch Methoden zur Verfügung. Der Controller ist dann nur noch dafür da, diese Methoden in der richtigen "Reihenfolge" bspw. bedingt durch Benutzeraktionen auszulösen.

Konkret am Beispiel:
Nehmen wir das Beispiel in dem die Schlange eine Frucht frisst. Für mich heisst MVC, dass das Modell eine Methode haben muss, herauszufinden, ob eine Frucht gefressen wird (schliesslich ist dies unabhängig der View (und Controller)).

Ich würde also im Modell SnakeModel eine Methode "hasEatenFruit" ähnlich wie von Marco13 vorgeschlagen implementieren.

Code:
public boolean hasEatenFruit(fruitModel){
 
if()...

return(true);

}

Um nun den Spielstand zu aktualisieren würde ich in der Klasse Gamestatus soetwas wie:

Code:
updatePoints(Fruit fruit){
 points=fruit.value+1;
}

schreiben.

Die Frage die sich nun stellt (und eigentlich die Eingangsfrage im Titel des Threads ist) ist, wo ich nun das fruitModel anpasse (eine Frucht wurde gefressen und muss also im Modell gelöscht werden). Oder in anderen Worten: Das Fressen einer Frucht löst zwei Modelländerungen aus. 1. Die Punkte in GameStatus werden erhöht. 2. Die Frucht wird aus dem fruitModel entfernt.

Ich sehe das mittlerweile so, dass beide Aktionen vom Controller ausgelöst werden sollten (und nicht von einem Modell das andere Modell benachrichtigt werden muss)

Code:
class Coneroller:

run(){

while(gameStatus.gameOver==false){
snake.move();
if(snake.hasEatenFruit()){
FieldPoint snakesHead = snake.getHeadsPosition(snakeModel)
Fruit eatenFruit fruitModel.getFruit(snakesHead)
gameStatus.updatePoints(eatenFruit )
}

}

So habe ich die "Business-Logik" in dem Sinne, dass alles was Manipulationen und Abfragen und Berechnungen im Modell selbst, deren Verknüpfung (nennen wir es Ablauflogik im Controller haben).

Das eigentliche Eingangsproblem/Threattitel (MVC: Kommunikation der Modellteile) löst sich dann insofern, als dass nicht ein Modell Änderungen des anderen Modelles auslösen muss. Die Modelle müssen sich nicht mehr kennen, alle Änderungen der Modelle werden "zentral" durch den Controller ausgelöst.

Seht ihr das auch so?/Einwände?
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Hab die Posts nicht wirklich durchgelesen. Hätte aber trotzdem eine Anmerkung:
Meiner Meinung sind Snake, Wall und Fruit alles Objekte ein und desselben (Game)Models.
 

editOr

Mitglied
Ja, die Bezeichnungen WallModel, FruitModel und SnakeModel sind sicher etwas irreführend. Tatsächlich sind sie einfach Bestandteile des Gesamtmodelles. Aber ob ich diese exlizit in eine Gesamtmodell (Game) packe und dann als ganzes übergebe, oder ob ich nur die einzelnen jeweils nötigen Teile übergebe ist in dem Sinne imo irrelevant.

Das Problem um das es hauptsächlich geht ist ja, dass mehrere Modell(bestandteile) gleichzeitig geändert werden müssen.
 

lilith2k3

Mitglied
Ich glaube mein Problem "Wo gehört was hin?" hat genau damit zu tun. Du setzt hier den Controller mit der Business-Logik gleich, das ist meiner Meinung nach gerade nicht der Fall. Nach etwas Googlen zeigt sich, dass das Gros aller Beiträge die Geschäftslogik im Modell sehen.

Nur weil es das Gros sagt, heißt es nicht, dass es richtig ist :p
Je nach Umsetzung kann die Geschäftslogik auch im Modell sitzen, ja. Ist aber Käse.
Das Modell sorgt dafür, dass es etwas zu präsentieren gibt. Und die View zeigt was. Der Rest wird von Controllern erledigt.

wenn das Modell nicht in irgendeinem Sinn observable ist
Warum sollte es das nicht sein? Ein Controller subscribed sich auf Updates am Objekt, welches ein anderer Controller auslösen kann. Warum sollte es nicht mehr observable sein?

Separation of Concerns impliziert nicht, dass man MVC verwendet (umgehehrt aber schon).
Das sage ich ja *lol*
Das Model kümmert sich ums Modell, die Controler um die Anpassungen von Modell und View, die View stellt dar. Fertig.

Hab die Posts nicht wirklich durchgelesen. Hätte aber trotzdem eine Anmerkung:
Meiner Meinung sind Snake, Wall und Fruit alles Objekte ein und desselben (Game)Models.
Ja. So ist es. Es sind Komponenten.

Die Frage die sich nun stellt (und eigentlich die Eingangsfrage im Titel des Threads ist) ist, wo ich nun das fruitModel anpasse (eine Frucht wurde gefressen und muss also im Modell gelöscht werden). Oder in anderen Worten: Das Fressen einer Frucht löst zwei Modelländerungen aus. 1. Die Punkte in GameStatus werden erhöht. 2. Die Frucht wird aus dem fruitModel entfernt.

Ja. Im "Game-Modell" werden diese beiden Zustände verändert.
Das Problem um das es hauptsächlich geht ist ja, dass mehrere Modell(bestandteile) gleichzeitig geändert werden müssen.
Und wo gibt es das Problem?
Es gibt ein Event "Frucht gefressen" und entsprechend kümmert sich ein Controler, der auf dieses Event subscribed ist, um die Auswertung dieses Ereignisses: "Frucht vom Feld nehmen, Punktestand aktualisieren und *PIEP* Geräusch machen" - resp. kannst Du auch mehrere Controler auf das Event lauschen lassen und jeder macht genau 1 Sache.

Was ist da problematisch?
 

lilith2k3

Mitglied
snakemvc.PNG - Bilder und Fotos kostenlos auf ImageBanana hochladen
So in etwa sähe dann die Komponentendarstellung aus.
Wobei ich hier eine MVVM Umsetzung gewählt habe (das Viewmodel repräsentiert hier quasi ein Stück Code/eine Klasse, welches den Spielzustand in Codeform enthält, was die Sache besser testbar gestaltet).
Könnte man auch weglassen, wobei man dann wieder bei MVC wäre.
Das Modell wird von der Game-Engine verwaltet und Updates am Modell führen dazu, dass diese auch gerendert werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Kommunikation mit Seriellen Schnittstellen + Integration einer lib Java Basics - Anfänger-Themen 1
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 9
D Klassen Klassen Kommunikation Java Basics - Anfänger-Themen 12
I Kommunikation "normaler PC" mit lokaler Software an "Cloud Service" und umgekehrt Java Basics - Anfänger-Themen 15
izoards Socket Kommunikation Java Basics - Anfänger-Themen 16
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 3
M konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln? Java Basics - Anfänger-Themen 8
A Client-Server Kommunikation Java Basics - Anfänger-Themen 3
S JavaFX-Arduino Kommunikation mit LCD-Anzeige Java Basics - Anfänger-Themen 0
A Kommunikation zwischen nebenläufigen Threads Java Basics - Anfänger-Themen 4
F Klassen Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 4
M Input/Output Kommunikation mit externen Geräten Java Basics - Anfänger-Themen 0
M OOP Kommunikation MVC und DTO Java Basics - Anfänger-Themen 13
K Kommunikation von Java RMI und Webservices Java Basics - Anfänger-Themen 9
H Einfache Client/Server-Kommunikation Java Basics - Anfänger-Themen 16
G Klassen Kommunikation zw. Klassen Java Basics - Anfänger-Themen 28
B Socket Kommunikation in beide Richtungen Java Basics - Anfänger-Themen 12
F Socket Kommunikation Java Basics - Anfänger-Themen 4
G Server-Client Kommunikation Java Basics - Anfänger-Themen 3
G Kommunikation zwischen zwei Klassen Java Basics - Anfänger-Themen 5
J Panel-übergreifende Kommunikation Java Basics - Anfänger-Themen 3
P Kommunikation zwischen zwei *.class Java Basics - Anfänger-Themen 3
J RxTx/RS232 Kommunikation (TwoWay) Java Basics - Anfänger-Themen 10
Z Tomcat Server Kommunikation zu Client Applet Java Basics - Anfänger-Themen 5
G Datenstruktur und die Kommunikation mit der GUI Java Basics - Anfänger-Themen 10
W Inter-Thread-Kommunikation Java Basics - Anfänger-Themen 3
M Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 3
T Kommunikation zwischen Controller und GUI Java Basics - Anfänger-Themen 2
S Frage zur Kommunikation zwischen Objekten Java Basics - Anfänger-Themen 5
J Kommunikation zwischen zwei JAVA-Dateien Java Basics - Anfänger-Themen 8
T Kommunikation zw. 2 Javaprogrammen Aufr --> Verab. -> Java Basics - Anfänger-Themen 6
P Kommunikation mit Prozess Java Basics - Anfänger-Themen 3
H Kommunikation C++ <> Java Java Basics - Anfänger-Themen 4
A Kommunikation Java-Anwendung <-> Java-Applet Java Basics - Anfänger-Themen 24
V Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 2
S Kommunikation zwischen Komponenten in einem JFrame Java Basics - Anfänger-Themen 10
D Thread und Process Kommunikation bei eigener Console Java Basics - Anfänger-Themen 2
P asynchrone Kommunikation Applet Servlet mit RMI möglich Java Basics - Anfänger-Themen 4
B Kommunikation zwischen Klasse und Listener Java Basics - Anfänger-Themen 2
F Kommunikation von 2 Klasse Java Basics - Anfänger-Themen 5
L Kommunikation zwischen mehreren Klassen Java Basics - Anfänger-Themen 2
B jtapi <-> tapi Kommunikation Java Basics - Anfänger-Themen 2
D Kommunikation zwischen zwei Java Anwendungen möglich? Java Basics - Anfänger-Themen 6
S Kommunikation zwsichen Klassen. Java Basics - Anfänger-Themen 9
D J/Direct oder JNI? .bzw. Kommunikation mit Windows-API. Java Basics - Anfänger-Themen 2
G Nochmal Problem mit Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 3
G Kommunikation zwischen Klassen, aber bitte MVC Java Basics - Anfänger-Themen 12
G Kommunikation zwischen Applet und Java-Anwendung über TCP/IP Java Basics - Anfänger-Themen 3
M Kommunikation zwischen GUI und Event -Klasse Java Basics - Anfänger-Themen 3
M probleme in der kommunikation von klassen Java Basics - Anfänger-Themen 5
Q Kommunikation zwischen Frames Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben