P. Pfahler, E. Stümpel

Programmieren in Java, Winter 1997/98

4. Übungsblatt, Lösungsvorschlag


Aufgabe 6 (Modellierung/Implementierung)

Es sollte ein Restaurant mit computergesteuertem Tischbelegungssystem modelliert und implementiert werden. Jede eintreffende Gästegruppe wird von diesem automatischen "Setzer" an einem der vorhandenen Tische plaziert, wobei die folgenden Bedingungen zu beachten sind: Folgende Klassenstruktur wurde vorgegeben:

   Tisch                   Restaurant    Gaeste    Setzer
     |
     +--RestaurantTisch

Hier wurde folgende "Verteilung der Aufgaben" gewählt:
Es folgen nun die Implementierungen der einzelnen Java Klassen:

Tisch.java zum Mitnehmen


public class Tisch 
{ protected int SitzPlätze;

  //Konstruktor
  public Tisch(int SitzPlätze)
    {
      this.SitzPlätze = SitzPlätze;
    }
}


RestaurantTisch.java zum Mitnehmen


public class RestaurantTisch extends Tisch
{ 
  private int TischNummer;
  private int frei;
  private Gaeste TischGaeste[] = new Gaeste[SitzPlätze];

  //Konstruktor
  public RestaurantTisch(int SitzPlätze, int TischNummer)
    {
      super(SitzPlätze);
      this.TischNummer = TischNummer;
      frei = SitzPlätze;
    }

  //gib Tischbelegung aus
  public void show()
    {
      System.out.print("Tisch " + TischNummer);
      System.out.print(" (" + SitzPlätze + " Plätze / ");
      System.out.println(frei + " freie Plätze)");
      for (int g = 0; g < TischGaeste.length; g++)
	{
	  if (TischGaeste[g] != null)
	    { 
	      System.out.print("\t");
	      TischGaeste[g].show();
	    }
	}
    }

  //wieviele Plätze sind noch frei?
  public int frei()
    {
      return frei;
    }

  //setze Gäste an den Tisch und kennzeichne Plätze als belegt
  public void plaziere(Gaeste g)
    {
      if (g.Anzahl() <= frei)
	{ // sie passen
	  for (int i = 0; i < TischGaeste.length; i++)
	    { // suche freien Platz im Array TischGaeste
	      if (TischGaeste[i] == null)
		{ // wir nehmen die Gäste auf
		  TischGaeste[i]=g;
		  frei -= g.Anzahl();
		  return;
		}
	    }
	}
      // sie passen nicht
      System.out.println("Sorry");
      g.show();
      System.out.println("passen nicht an Tisch " + TischNummer);
    }

  //mache Belegung durch die Gruppe rückgängig  
  public boolean freimachen(Gaeste g)
    { // prüfen, ob die Gäste an diesem Tisch sitzen
	  for (int i = 0; i < TischGaeste.length; i++)
	    { 
	      if (TischGaeste[i] == g)
	      { // wir machen die Plätze frei
		TischGaeste[i]=null;
		frei += g.Anzahl();
		return true;
	      }
	    }
	  return false;
    }

  //Tisch leer?
  public boolean leer()
    { // sitzt keiner am Tisch
      return frei == SitzPlätze;
    }
}


Restaurant.java zum Mitnehmen


public class Restaurant
{
  private String name;
  private RestaurantTisch Tische[];
  private int toptisch = 0;

  //Konstruktor
  public Restaurant(String name, int MaxTisch)
    {
      this.name = name;
      Tische = new RestaurantTisch[MaxTisch];
    }

  //stelle Tisch auf
  public void add(RestaurantTisch t)
    { 
      Tische[toptisch++] = t;
    }

  //aktuelle Belegung der Tische
  public void show()
    {
      System.out.println();
      for (int t=0; t < toptisch; t++)
	{
	  Tische[t].show();
	}
    }

  //Plazierung für die Gästegruppe finden
  public void kommen(Gaeste g)
    {
      final int KEINER = -1;
      int tisch = KEINER;  // die Gäste sollen an Tische[tisch] sitzen
      // wir waehlen den kleinsten passenden leeren Tisch

      for (int t=0; t < toptisch; t++)
	{
	  if (Tische[t].leer())
	    { // reichen die Plätze?
	      if (Tische[t].frei() >= g.Anzahl())
		{ // schon vorher einen gefunden?
		  if (tisch != KEINER)
		    { // nimm den kleineren der beiden
		      if (Tische[t].frei() < Tische[tisch].frei())
			{
			  tisch = t;
			}
		    }
		  else tisch = t;
		}
	    }
	}

      // wenn kein passender frei war, versuchen wir die Gäste an einem
      // schon teilweise besetzten Tisch zu plazieren

      if (tisch == KEINER)
      for (int t=0; t < toptisch; t++)
	{ // reichen die Plätze
	  if (Tische[t].frei() >= g.Anzahl())
	    { // schon vorher einen gefunden?
	      if (tisch != KEINER)
		{ // nimm den kleineren der beiden
		  if (Tische[t].frei() < Tische[tisch].frei())
		    {
		      tisch = t;
		    }
		}
	      else tisch = t;
	    }
	}

      if (tisch == KEINER)
	{ // Tschuldigung
	  System.out.println("Sorry ");
	  System.out.print("\t");
	  g.show();
	  System.out.println("finden im Moment keinen Platz\n");
	}
      else 
	{
	  Tische[tisch].plaziere(g);
	}
    }

  //Tischbelegung rückgängig machen
  public void gehen(Gaeste g)
    {
      for (int t=0; t < toptisch; t++)
	{
	  if (Tische[t].freimachen(g))
	    return;
	}
      System.out.println("Sorry ");
      System.out.print("\t");
      g.show();
      System.out.println("können nicht gehen, da sie gar nicht da sind\n");
    }
}


Gaeste.java zum Mitnehmen


public class Gaeste
{
  private String Name;
  private int Anzahl;

  //Konstruktor
  public Gaeste(String Name, int Anzahl)
    {
      this.Name = Name;
      this.Anzahl = Anzahl;
    }

  //Gib alle Infos aus
  public void show()
    {
      System.out.println(Name + ", " + Anzahl + " Personen");
    }

  //gib Personenzahl aus
  public int Anzahl()
    {
      return Anzahl;
    }
}


Setzer.java zum Mitnehmen


public class Setzer
{ private Restaurant r;
  public Setzer(Restaurant r)
    {
      this.r = r;
    }
  
  //versuche die Gäste an einem geeigntem Tisch zu plazieren
  public void kommen(Gaeste g)
    {
      r.kommen(g);
    }

  //mache die getroffene Belegung wieder rückgängig
  public void gehen(Gaeste g)
    {
      r.gehen(g);
    }

  //gibt aktuelle Belegung des Restaurants aus
  public void zeigeBelegung()
    {
      r.show();
    }

}

ANMERKUNG

Die Implementierung des Plazierungsverfahrens liegt bei unserem Lösungsvorschlag in der Klasse Restaurant, was programmiertechnisch von Vorteil ist (direkter Zugriff auf das Array von Tischen). Die Klasse Setzer übernimmt hier lediglich die oberste Steuerungsebene durch den Aufruf der passenden Methoden aus Restaurant.

Diese Lösung ist als eine mögliche Lösung zu sehen und nicht zwingend. Eine andere Lösung ist es beispielsweise, das gesamte Plazierungsverfahren als Aufgabe der Klasse Setzer anzusehen und somit auch dort zu implementieren.

Wir sprechen daher bewußt von Lösungsvorschlägen und nicht von Musterlösungen.