Laden...

Übungsaufgabe: Ampel

Erstellt von BillTuer vor 17 Jahren Letzter Beitrag vor 17 Jahren 4.022 Views
B
BillTuer Themenstarter:in
325 Beiträge seit 2005
vor 17 Jahren
Übungsaufgabe: Ampel

Hallo Forum,
ich habe hier eine Übungsaufgabe, an der ich jetzt eine ganze Weile geknobelt habe.
Zu einer Lösung bin ich auch gekommen, aber irgendwie habe ich das Gefühl, dass das Ergebnis ein wenig anders aussehen sollte.

Aufgabe:

Wir modellieren ein Verkehrsampel in einfachster Form. Eine Ampel
kann die Farben rot, gelb und grün anzeigen (mit enum). Eine Ampel kann
geschaltet werden, d. h. falls die Farbe rot ist wird sie zunächst gelb und kurz
darauf grün, falls die Farbe grün ist wird sie zunächst gelb und kurz darauf
rot. Das Interface IBetrieb enthält die Methode schalten(). Schalten Sie in
Main die Ampel in einer Schleife unter Verwendung des Interfaces.
Geben Sie jeweils die aktuelle Farbe der Ampel durch Überschreiben
von ToString() aus, wobei das Umschalten durch ein
kurzes Warten erkennbar wird (möglichst realitätsnah).

Meine Lösung sieht wie folgt aus:

    interface IBetrieb
    {
        void Schalten();
    }

    class Ampel : IBetrieb
    {
        public enum Farbe
        {
            rot,
            gelb,
            gruen
        }

        Farbe farbe = Farbe.rot;

        public void Schalten()
        {
            if ( ToString() == "rot" )
            {
                for (int i = 0; i < 3; i++)
                {
                    Console.WriteLine(ToString());
                    farbe = farbe + 1;
                    System.Threading.Thread.Sleep(500);
                }
            }
            else if (ToString() == "gruen")
            {
                for (int i = 3; i > 0; i--)
                {
                    Console.WriteLine(ToString());
                    farbe = farbe - 1;
                    System.Threading.Thread.Sleep(500);
                }
            }
        }

        public override string ToString()
        {
            return farbe.ToString();
        }
    }
    
    class Program
    {        
        static void Main(string[] args)
		{
            Ampel ampel = new Ampel();
            ampel.Schalten();
			
            Console.Read();
		}
    }

Wie hättet ihr die Aufgabe gelöst?
Kann man meine Lösung durchgehen lassen?

Danke 🙂

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo BillTuer,

ich denke, die Lösung ist ganz ok (Wie gut sie ist, hängt ja immer davon ab, wie genau man die Vorstellungen/Erwartungen des Aufgabenstellers getroffen hat).

Allerdings hast du noch einen Fehler drin: farbe liegt nach dem Schalten außerhalb des gültigen Wertebereichs.

herbivore

3.003 Beiträge seit 2006
vor 17 Jahren

Das schreit einem "STATE" ins Gesicht 😉.

http://de.wikipedia.org/wiki/Zustand_(Entwurfsmuster)

Viel Spass.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
BillTuer Themenstarter:in
325 Beiträge seit 2005
vor 17 Jahren

@ herbivore
Danke. Könntest du das bitte kurz erläutern?

@ LaTino
Da kümmere ich mich in ein paar Wochen drum 😉

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo BillTuer,

was gibt es da zu erläutern? Im Zweifel guck es dir mit dem Debugger an. Du kannst auch testweise im Main zweimal schalten. Dann wirst du sehen, dass dein Programm nicht funktioniert.

herbivore

3.003 Beiträge seit 2006
vor 17 Jahren

Nein, ich hatte keine Langeweile - ich drücke mich nur um meine Arbeit 😉.


using System;

namespace StatePatternAmpel
{
	class Program
	{
		static void Main(string[] args)
		{
			Ampel myAmpel = new Ampel();
			for (int i = 0; i < 10; i++)
				myAmpel.Schalten();
			Console.Read();
		}
	}

	public interface IBetrieb
	{
		void Schalten();
	}

	public interface IMyState
	{
		void Show(Ampel ampel);
	}

	public class ZeigtGruenState : IMyState
	{
		public static readonly ZeigtGruenState Singleton = new ZeigtGruenState();

		public void Show(Ampel ampel)
		{
			Console.WriteLine("Ich bin grün!");
			ampel.StateAendern(ZeigtGelbState.Singleton);
		}
	}

	public class ZeigtGelbState : IMyState
	{
		public static readonly ZeigtGelbState Singleton = new ZeigtGelbState();

		public void Show(Ampel ampel)
		{
			Console.WriteLine("Ich bin gelb!");
			if (ampel.lastStatus is ZeigtRotState)
				ampel.StateAendern(ZeigtGruenState.Singleton);
			else
				ampel.StateAendern(ZeigtRotState.Singleton);
		}
	}

	public class ZeigtRotState : IMyState
	{
		public static readonly ZeigtRotState Singleton = new ZeigtRotState();

		public void Show(Ampel ampel)
		{
			Console.WriteLine("Ich bin rot!");
			ampel.StateAendern(ZeigtGelbState.Singleton);
		}
	}

	public class Ampel : IBetrieb
	{
		private IMyState status;
		internal IMyState lastStatus;

		public Ampel()
		{
			status = ZeigtRotState.Singleton;
			lastStatus = ZeigtGelbState.Singleton;
		}

		public void StateAendern(IMyState newState) 
		{
			lastStatus = status;
			status = newState;
			System.Threading.Thread.Sleep(500);
		}


		public void Schalten()
		{
			status.Show(this);
		}
	}


}

Wenn euer Lehrer nur sehen will, dass ihr mit Interfaces umgehen könnt - hieran müsste er es eigentlich sehen 😉.

Grüße,

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
BillTuer Themenstarter:in
325 Beiträge seit 2005
vor 17 Jahren

@ herbivore
Sorry, habe gepostet ohne über deinen Beitrag nachzudenken.
Habe es jetzt geändert, auch mehrmaliges schalten hintereinander klappt nun:


if ( ToString() == "rot" )
            {
                for (int i = 0; i < 3; i++)
                {
                    farbe = (Farbe)i;
                    Console.WriteLine(ToString());
                    System.Threading.Thread.Sleep(500);
                }
            }
            else if (ToString() == "gruen")
            {
                for (int i = 2; i > -1; i--)
                {
                    farbe = (Farbe)i;
                    Console.WriteLine(ToString());
                    System.Threading.Thread.Sleep(500);
                }
            }

@ LaTino
Ähm, ok 🙂 Werde mir das bei Gelegenheit Mal anschauen und versuchen, es zu verstehen. Danke!

B
BillTuer Themenstarter:in
325 Beiträge seit 2005
vor 17 Jahren

PS: gibt es eigentlich eine Konvention dafür, ob man die "Main-Klasse" ganz oben stehen läßt und den Rest darunter anordnet bzw. umgekehrt?

3.003 Beiträge seit 2006
vor 17 Jahren

Die Konvention lautet, jede Klasse in eine eigene Datei zu verfrachten 🙂.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
BillTuer Themenstarter:in
325 Beiträge seit 2005
vor 17 Jahren

Hehe, und wenn sich das für gewisse Programme nicht lohnt? 🙂

3.003 Beiträge seit 2006
vor 17 Jahren

Hm, du wolltest die Konvention wissen 😄. Ansonsten ist es einfach Geschmackssache, denke ich.
Leute, die eher vom strukturierten Programmieren (C und Konsorten) kommen, werden bei der Reihenfolge eher darauf achten, dass die logische Reihenfolge eingehalten wird - also dass man sich nie auf etwas bezieht, das erst weiter unten deklariert wird.

Andere - ich zum Beispiel - schreiben den Code, der "wichtiger" ist, dh. der eher umgeschrieben wird, nach oben. Findet sich später leichter.

Das kannst du aber halten wie ein Dachdecker. Puristen würden sagen, dass es keine Situation gibt, in der es sich "nicht lohnt".

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

T
512 Beiträge seit 2006
vor 17 Jahren

Ich würde nur anmerken, dass du den Umweg über ToString() nicht brauchst. Frag die Farbe direkt ab:


if( farge == Farbe.rot )
...

oder mach gleich ein switch:


switch( farbe )
{
    case Farbe.rot:
        ...
        break;

    case Farbe.gruen:
        ...
        break;
}

e.f.q.

Aus Falschem folgt Beliebiges

R
494 Beiträge seit 2006
vor 17 Jahren

Original von BillTuer
Hehe, und wenn sich das für gewisse Programme nicht lohnt? 🙂

Wieso soll sich das nicht lohnen?
In wieviele Dateien der Code gesplittet ist, ist doch realtiv egal, das Ergebnis wird auf jedenfall nicht beeinflusst.