Laden...

Wo das einzige Objekt zur Klasse erstellen, sodass es an den benötigten Stellen zur Verfügung steht?

Erstellt von fortuneNext vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.053 Views
F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren
Wo das einzige Objekt zur Klasse erstellen, sodass es an den benötigten Stellen zur Verfügung steht?

Hallo,
ich und ein paar Freunde sind neu im C#. Vorher haben wir fast alle in Delphi programmiert. Nun wollen wir als unser erstes gemeinsames Projekt ein Minispiel bauen. Es ist keine von diesen riesigen Sachen, die sich die Leute immer am Anfang vorstellen, bis sie auf den Boden der Tatsachen geholt werden, sondern wirklich eine sehr sehr einfache Sache. Ich habe inzwischen schon einige Tutorials zu C# gelesen (z.B. den guidetocsharp), bin leider aber noch recht wenig zum praktischen OOP-coden gekommen.
Nun haben wir also dazu das "Programm" erstmal in 2 Namespaces geteilt - den Hauptnamespace "Output", der später die Übertragung der Daten an die Form steuern soll, und "Mechanics", wo das Spiel an sich abläuft.
Nun möchte ich also erstmal einen Platz für die ganzen verschiedenen Werte schaffen, die so im Laufe des Spiels abgespeichert werden müssen. Also habe ich im Namespace "Mechanics" die Klasse "Game" erstellt.

namespace Mechanics
{
    public class Game
    {
        class Player
        {
            int hitpoints
            {
            }
        }

        class Slot
        {
        }
    }
}

Nicht sonderlich komplex oder vollständig.

Hier die erste Zwischenfrage: Gibt es vielleicht in C-Sharp eine sauberere Möglichkeit für Klassen, die ohnehin nur 1x verwendet werden - so in Richtung einer Klasse, die von Anfang an als Objekt initialisiert ist, aber von der keine neuen Instanzen erzeugt werden können? (Hat das vielleicht was mit "Static" zu tun?)

Das Hauptproblem ist aber ein Anderes:
Bekanntlich muss ja nun ein Objekt dieser Klasse erzeugt werden. Nun frage ich mich: Wo zum Henker tue ich das?
Im Namespace geht nicht und wäre auch ohnehin als globale Variable ein unheimlich schlechter Stil. In die Klasse selber eine Instanz von ihr einzubauen scheint auch irgendwie paradox.
In die Form vielleicht? Einfach hineindefinieren?

Mechanics.Game Test1;
//oder
Mechanics.Game Test1 = new Mechanics.Game();

Hier wird der Name "Test1" in den FormMethoden nicht gefunden, wenn ich es mitten in die Formdefinition schreibe. Im form_Main(), also der Initialisierung, würde es ja nur lokal sein, das kann daher auch nicht die Lösung sein.
Allgemein wollten wir die Form allerdings nur als Eingabe nutzen, nicht als Steuerelement. Die Steuerung soll in den "Mechanics" liegen, das meiste davon in der Klasse "Game". Das "Game" also nur als lokale Variable in der Form zu deklarieren, erscheint also auch sehr suboptimal, schließlich soll das Game-Objekt in der ganzen Anwendung verfügbar sein, nach Möglichkeit dort auch im NameSpace "Mechancis".
Lange Rede, kurzer Sinn:
Wo lege ich das Objekt richtig an, sodass es überall verfügbar ist?

Danke schonmal =)
fortuneNext

2.223 Beiträge seit 2005
vor 14 Jahren

Hallo fortuneNext,

zur ersten Frage kannst du mal nach dem Singleton Pattern suchen.

solange sich deine zweite Frage auf das Singelton Objects bezieht erklärt sich das von selber soblad du etwas darüber gelesen hast

kleine Empfehlung am rande, Denkt doch mal über eine Business Logik klasse nach
denn in die Form gehört eigentlich keine wirkliche logik rein, wäre aber nur um einer Design ein wenig aufzuhübschen

Herzliche Grüße
Lars

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo fortuneNext,

wenn du ein Objekt nur einmal verwenden willst (=> nur eine Instanz des Objektes erhalten möchtest), kannst du das Singleton-Entwurfsmuster verwenden (wobei das mit Vorsicht zu genießen ist).

Die Frage, wo bzw. wie du ein Objekt erzeugst, ist wirklich relativ elementar: s. :rtfm:, 🛈 & 📗 (ich verweise auf die Openbooks wg. [Hinweis] Wie poste ich richtig? Punkt 1.1.1).

m0rius

Edit: Da war jemand schneller. Typo.

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Hey,
vielen Dank für den Tipp mit den Singletons - werde ich mal in betracht ziehen. 😃

@ m0rius: In diese Guides habe ich ja - wie angemerkt - schon geschaut. Leider konnte ich dort keine Antwort finden. Wie ein Objekt erzeugt wird, ist mir ja klar - aber wo jetzt in meinem Anwendungsschema der richtige Ort ist, ist mir unklar. Und ich frage ja genau deshalb nach, weil ich aus den Openbooks eben nicht schlauer geworden bin. 😃
Danke trotzdem schonmal für die Hilfe =)
fortuneNext

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo fortuneNext,

prinzipiell gilt, dass Variablen bzw. Objekte nur dort verfügbar sein sollen, wo sie gebraucht werden. Entsprechend sollten sie möglichst nah an ihrem "Einsatzort" erzeugt werden.
Globale Variablen sind kein guter Stil und sollten nach Möglichkeit vermieden werden.

Hier ein kleines Beispiel (das Programm gibt x "zufällige" (s. Wie zufällig ist Radnom.Next?) Zahlen aus):

using System;

namespace m0rius.RandomNumberGenerator
{
    class RandomNumberGenerator
    {
        public int[] GetRandomNumbers(int x)
        {
            Random rnd = new Random();
            int[] randomNumbers = new int[x];

            for (int i = 0; i < x; i++)
            {
                randomNumbers[i] = rnd.Next();
            }     

            return randomNumbers;
        }
    }
}

namespace m0rius.RandomNumberGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            // Hier wird der RandomNumberGenerator erzeugt
            RandomNumberGenerator rng = new RandomNumberGenerator();
            int x = 10;

            int[] randomNumbers = rng.GetRandomNumbers(x);

            foreach (int number in randomNumbers)
            {
                Console.Write(number + " ");
            }
        }
    }
}

In dieser Konsolenanwendung wird der RandomNumberGenerator in der Main-Methode erzeugt, weil er nur dort verwendet wird.
Würde eine andere Methode den Generator ebenfalls verwenden, könnte man diesen auch als statisches Feld der Klasse implementieren.

Um auf deine Frage zurückzukommen: static selbst hat mir globaler Verfügbarkeit nichts zu tun!

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Hey, danke erstmal für die Antwort. Leider ist sie nur begrenzt hilfreich 😦

prinzipiell gilt, dass Variablen bzw. Objekte nur dort verfügbar sein sollen, wo sie gebraucht werden. Entsprechend sollten sie möglichst nah an ihrem "Einsatzort" erzeugt werden.
Globale Variablen sind kein guter Stil und sollten nach Möglichkeit vermieden werden.

Das entspricht ja etwa genau dem, was ich schon im ersten Post geschrieben habe.

Im Namespace geht nicht und wäre auch ohnehin als globale Variable ein unheimlich schlechter Stil

Dein Beispiel zeigt leider auch nur eine lokale Variable im Main(). Lokal ist aber für mich leider nicht möglich, zumindest nicht so - denn die Werte müssen ja beibehalten bleiben, um sie später wieder aufrufen zu können. Außerdem wird das Objekt nach Main() im Beispiel verworfen. Ich muss mit dem Objekt aber die gesamte Zeit über rechnen können. Auch eine Implementierung in die Form ist - wie gesagt - eher suboptimal, da ich eigentlich den Hauptprogrammcode nicht für die Form vorgesehen hatte. Mein Objekt soll eine Art globaler Datenspeicher für alle relevanten Daten sein - er muss sowohl für die Mechanics als auch für das Ein/Ausgabewerk verfügbar sein, da letztere das Objekt ja mit Daten speisen bzw. seine Daten interpretieren und ausgeben.

Würde eine andere Methode den Generator ebenfalls verwenden, könnte man diesen auch als statisches Feld der Klasse implementieren.

Um auf deine Frage zurückzukommen: static selbst hat mir globaler Verfügbarkeit nichts zu tun!

Dieser Teil klingt relativ nützlich. Leider verstehe ich ihn nicht. Den Generator als statisches Feld der Generatorklasse? Ist das nicht paradox?
Was genau hat es denn mit dem statisch auf sich? Es macht etwas klassenbezogen statt objektbezogen (zusammenfassung der Guides), wenn ich das richtig verstehe. Hierzu würde mir jedoch ein praktisches Beispiel denke ich besser veranschaulichen, wie das gemeint ist bzw. wie es sich anwenden lässt. Wie z.B. das nämlich dafür sorgen soll, dass in deinem Fall der Generator noch anderen Methoden zugänglich wäre, kann ich nicht sehen.

Im Endeffekt brauche ich auf jeden Fall einen Datenspeicher. Die Daten sind für alle Teile des Programms wichtig und dürfen eben nicht gelöscht werden. Als lokale Variable für die Form wäre ebenso schlecht wie eine globale Variable, da die Form in der Anwendung nicht der Hauptkontrollpunkt werden soll, sondern eben das Objekt. Außerdem könnte man dann eben nicht von anderen Klassen darauf zugreifen.

Danke für die Mühe, die ihr euch macht =)

fortuneNext

U
1.688 Beiträge seit 2007
vor 14 Jahren

Hallo,

hast Du Dir schon, wie empfohlen, das Singleton-Muster angeschaut? Damit sollten einige Deiner Fragen beantwortet sein.

Ansonsten - verwende den kleinsten Gültigkeitsbereich der Variablen, der möglich ist, sodass noch alle Teile Zugriff haben. Und wenn das die Klasse ist, dann ist das eben so. Wirklich "globale" Variablen gibt's ja sowieso nicht.

PS: Deine Anfängerfrage ist nicht blutig - auch wenn Du meinst es wäre eine Frage eines blutigen Anfängers...

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo fortuneNext,

Das entspricht ja etwa genau dem, was ich schon im ersten Post geschrieben habe.

nun ja, das war meine Antwort auf deine Frage "Wo zum Henker tue ich das?".

denn die Werte müssen ja beibehalten bleiben, um sie später wieder aufrufen zu können.

Das Beispiel sollte auch nur demonstrieren, wo die Objekt-Erzeugung in einem speziellen Fall Sinn macht. Wie du schon gesagt hast, sind diese Daten nach dem Verlassen der Methode Main aufgrund der lokalen Verfügbarkeit nicht mehr zugreifbar.

Ich muss mit dem Objekt aber die gesamte Zeit über rechnen können.

Da hast du dir deine Frage praktisch selbst beantwortet: Du darfst die Daten nicht lokal in einer Methode erzeugen, sondern z.B. als Feld bzw. Eigenschaft einer Klasse.

Auch eine Implementierung in die Form ist - wie gesagt - eher suboptimal, da ich eigentlich den Hauptprogrammcode nicht für die Form vorgesehen hatte.

Genau! Die Speicherung von Daten hat in der GUI nach der 3-Schichten-Architektur absolut nichts verloren.

Mein Objekt soll eine Art globaler Datenspeicher für alle relevanten Daten sein - er muss sowohl für die Mechanics als auch für das Ein/Ausgabewerk verfügbar sein, da letztere das Objekt ja mit Daten speisen bzw. seine Daten interpretieren und ausgeben.

An der Stelle musst du konkreter werden: Was soll da für wen zugänglich gespeichert werden? Dem "globalen Datenspeicher" stehe ich in der Form erstmal skeptisch gegenüber.

Den Generator als statisches Feld der Generatorklasse? Ist das nicht paradox?

Nein. Sobald der Generator in diesem Beispiel von mehreren Methoden verwendet wird, macht es Sinn, ihn als privates Feld bzw. als private Eigenschaft der Klasse zu implementieren. Dass man ihn in diesem Fall statisch machen muss, liegt daran, dass aus einem statischen Kontext wie der Main-Methode nicht auf nicht-statische Elemente der Klasse zugegriffen werden kann.

Es macht etwas klassenbezogen statt objektbezogen

Zustimmung.

Wie z.B. das nämlich dafür sorgen soll, dass in deinem Fall der Generator noch anderen Methoden zugänglich wäre, kann ich nicht sehen.

S. obige Erklärung. Ist der Generator - aufgrund der angestrebten Kapselung als privates - Feld angelegt (und in unserem Konsolen-Beispiel zusätzlich statisch), kann er innerhalb der Klasse von Methoden verwendet werden

Im Endeffekt brauche ich auf jeden Fall einen Datenspeicher. Die Daten sind für alle Teile des Programms wichtig und dürfen eben nicht gelöscht werden.

Wie gesagt, diesen Teil müsstest du nochmal präzisieren.

Außerdem könnte man dann eben nicht von anderen Klassen darauf zugreifen.

Das ist der knifflige Teil an der Architektur. Es soll ja nicht von jeder beliebigen Stelle aus auf die Daten lesend bzw. schreibend zugegriffen werden können.
So verlockend, wie das Singleton-Entwurfsmuster auch erscheint, birgt es auch einige (Design-)Gefahren und verleitet zu falscher Nutzung. Selbst die Entwickler des Patterns sehen dieses mittlerweile als zweischneidiges Schwert.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

5.299 Beiträge seit 2008
vor 14 Jahren

Hi fortuneNext!

Ich würde das mit der Schichten-Architektur nicht so hoch aufhängen.
Bei den 3-Schichten-Solutions, die ich bisher gesehen hab, hatte ich immer das Gefühl, da wird immenser Aufwand getrieben, weniger, um den Code transparent zu kriegen, als, um den Pattern zu befriedigen.

Wenn du sagst, dein Spiel bleibt klein, dann kannste als Datengrundlage ein typisiertes Dataset dir modellieren, wasde mit .ReadXml einliest, und mit .WriteXml abspeicherst.

Das kannste in einer Singleton-Klasse geschehen lassen, und hast ein Super-flexibles und mächtiges Daten-Verwaltungs-Instrument.

Guggemal Singleton-Dataset

Um son Dataset zu konfigurieren schreibt man keinen Code, sondern öffnets im Dataset-Designer - da kannman Tabellen und Relationen gestalten wie mans braucht.

Der frühe Apfel fängt den Wurm.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo fortuneNext,

In die Klasse selber eine Instanz von ihr einzubauen scheint auch irgendwie paradox.

ist es aber nicht. Klasse und Objekt ist ja nicht das gleiche. Statische Methoden gehören zur Klasse nicht zu einem bestimmten Objekt. In einer statischen Methode ein Objekt der Klasse zu erzeugen ist nichts ungewöhnliches. Das Problem scheint mir weniger das Erzeugen des Objekts zu sein, als vielmehr die gedankliche Beschränkung, die du dir selbst unnötigerweise auferlegst.

Natürlich sollte man globale Variablen verhindern. Aber ich sehe hier nicht, wo du eine globale Variable brauchst. So wie ich es verstehe, soll das Game-Objekt das Spiel steuern. Das heißt das Game-Objekt benutzt die anderen Klassen und Objekte, nicht umgekehrt. Keine der anderen Klassen muss die Klasse Game kennen und sollte das auch nicht . Alles eine Frage der Richtung, in der der Zugriff erfolgt.

Wenn du also ein Game-Objekt in einer statischen Methode der Klasse Game erzeugst und dieses Game-Objekt z.B. einen Timer erzeugt und der Elapsed-EventHandler eine (nicht-statische) Methode der Klasse Game ist, hast du über dort this Zugriff auf Game-Objekt. Mehr brauchst du eigentlich nicht.

herbivore

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Aha, nun langsam beginne ich das Ganze langsam zu verstehen 😃

hast Du Dir schon, wie empfohlen, das Singleton-Muster angeschaut? Damit sollten einige Deiner Fragen beantwortet sein.

Angeschaut ja, allerdings blicke ich dank meiner mangelnden C#-Kenntnis noch nicht alzu gut durch, da ich noch nichtmal wirklich Syntax-sicher bin. Aber ich schaue es mir trotzdem genau an. Allerdings versuche ich trotzdem, das auch noch ohne das Muster hinzukriegen - sonst stoße ich beim nächsten Projekt wieder auf dasselbe Problem. 😃

Ansonsten - verwende den kleinsten Gültigkeitsbereich der Variablen, der möglich ist, sodass noch alle Teile Zugriff haben. Und wenn das die Klasse ist, dann ist das eben so. Wirklich "globale" Variablen gibt's ja sowieso nicht.

Jau, genau das habe ich vor. Mit den Grundregeln der OOP bin ich ja vertraut (aus Delphi) 😃
Aber einfach formuliert stehe ich ja vor der Problematik: Ich habe 2 verschiedene Dinge, die auf derselben Ebene stehen und beide dasselbe Objekt verwenden sollen. Aber: Eine Ebene höher kann ichs nicht deklarieren, denn dann wäre es global.

PS: Deine Anfängerfrage ist nicht blutig - auch wenn Du meinst es wäre eine Frage eines blutigen Anfängers...

Keine Sorge, das ist Absicht - Angewöhnung, ich hab den Fehler mal gemacht und formulier es seitdem immer so 😃

Da hast du dir deine Frage praktisch selbst beantwortet: Du darfst die Daten nicht lokal in einer Methode erzeugen, sondern z.B. als Feld bzw. Eigenschaft einer Klasse.

Genau das habe ich ja auch versucht - die ganzen Werte als Eigenschaften der Game-Klasse zu speichern. Aber nun kann ich ja schlecht die Game-Klasse in noch eine Klasse einbetten, und die widerrum in eine Weitere usw.

Genau! Die Speicherung von Daten hat in der GUI nach der 3-Schichten-Architektur absolut nichts verloren.

Eben. 😃
Das Problem ist eben, dass die Klasse die Steuerungsschicht ist, und nicht die Form, was aber bedeutet, dass das Objekt der Klasse nicht in der Form erstellt werden darf, sondern irgendwo anders!

An der Stelle musst du konkreter werden: Was soll da für wen zugänglich gespeichert werden? Dem "globalen Datenspeicher" stehe ich in der Form erstmal skeptisch gegenüber.

Hmm, ich hatte gehofft, das geht aus meinem ersten Post hervor. Es sind einfach die grundlegenden Spielelemente. Die "Lebenspunkte" der Spieler, ihre Karten usw. Sowas habe ich dann - wie im Code ganz oben - in die Klasse "Player" gekapselt, welche widerrum Bestandteil der Klasse "Game" ist. Game ist damit also die jenige Klasse, in der die Daten geschrieben werden, die später noch gebraucht werden*. Im ersten Moment muss sie erstmal für sich selber zur Verfügung stehen, damit sie mit den Daten aus sich selbst rechnen kann. Aber auch das Ausgabewerk muss (lesenden) Zugriff haben, um die Werte auf die Grafikebene zu projezieren, während das Eingabewerk auch eingegebene Spielbefehle an die Klasse weiterleiten muss. Hierzu würde ich gerne eine "Schnittstelle" in Form einer einzelnen Methode der Game-Klasse verwenden, in die sämtliche eingegebenen Daten eingespeist werden und die GameKlasse sie verarbeitet und entsprechend zuweist.

*Hier würde eine kleine Zwischenfrage mir schon helfen, die das Problem auf ein sehr elementares Niveau herabsenkt:
Wie schreibe ich ein Programm, in dem der User eine Zahl eingibt, und diese wird gespeichert und bei einem Buttonklick ausgegeben? Die Zahl soll dabei aber ausdrücklich nicht Form-gebunden gespeichert werden!

Nein. Sobald der Generator in diesem Beispiel von mehreren Methoden verwendet wird, macht es Sinn, ihn als privates Feld bzw. als private Eigenschaft der Klasse zu implementieren. Dass man ihn in diesem Fall statisch machen muss, liegt daran, dass aus einem statischen Kontext wie der Main-Methode nicht auf nicht-statische Elemente der Klasse zugegriffen werden kann.

Das klingt nach etwas sehr Nützlichem, vielleicht genau dem, was ich brauche. Leider kann ich mir noch nicht wirklich etwas Konkretes darunter vorstellen. Hätte vielleicht jemand ein ganz simples Codebeispiel für die Verwendung solcher statischen Sachen?

Das ist der knifflige Teil an der Architektur. Es soll ja nicht von jeder beliebigen Stelle aus auf die Daten lesend bzw. schreibend zugegriffen werden können.
So verlockend, wie das Singleton-Entwurfsmuster auch erscheint, birgt es auch einige (Design-)Gefahren und verleitet zu falscher Nutzung. Selbst die Entwickler des Patterns sehen dieses mittlerweile als zweischneidiges Schwert.

Richtig. Aber es soll sich auch nicht nur um eine lokale Sache handeln. Und wie oben erwähnt, müssen die anderen Teile trotzdem Zugriff erhalten.
Mit dem Singleton-Pattern beschäftige ich mich zwar, lasse es aber aus etwa diesen Gründen aus meiner Erstlösung erstmal heraus - vielleicht würden sich ja meine Probleme lösen, aber für die Erstlösung würde ich gern erstmal den "konventionellen" Weg erlenen.

@ Erfinder des Rates: Das Ding dient halt hauptsächlich zur Übung von C#. Ich will dabei lernen - deshalb versuch ichs, wie gesagt, nicht mit Alternativen, sondern den konventionellen Methoden. Trotzdem danke =)

@ herbivore: Hmm, in gewisser Weise brauchen die anderen schon Zugriff. Siehe vielleicht Skizze. 😃
Generell würde mir für das mit diesen statischen Objekten in der Klasse wirklich ein Codebeispiel helfen. Vond er Logik her verstehe ich das einigermaßen, aber wie das nun tatsächlich aussehen soll, weiss ich nicht wirklich.

Im Anhang hab ich mal die Anwendungsstruktur versucht zu skizzieren. Vielleicht hilft es ja ein bischen beim Verständnis 😃 Die farbigen Pfeile sind Eingabebeispiele.
Danke nochmal für die ganzen Mühen!

5.299 Beiträge seit 2008
vor 14 Jahren

Hmm. Ich würde das eher Objektorientiert planen, wobei ich mich an Objekten ausse Realität orientierte:

Da gibts spieler, Karten, den Kartenstapel.
Vermutlich Spielzüge und Runden.

ZB kannich deiner Grafik nicht entnehmen, ob mehrere Spieler vorgesehen sind, oder nur einer.

Bei mehreren: Wie macht mans, dass die sich nicht in die Karten gucken, am Bildschirm?

Jo, jetzt müssteman dringend wissen, welches Spiel du implementieren willst, ob ein Spieler eine Stiche-Auflistung bekommt, ob Manschaften gebildet werden (Skat, Doppelkopf), oder ob ein Spieler Chips haben muß (Poker).

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Das Teil ist ja im Prinzip Objektorientiert, oder? Es ist halt nicht alzu detailliert. Solche Fragen hab ich mir alle schon gestellt 😉 Die Regeln hab ihc mir selbst ausgedacht, es sind 2 Spieler, und Kartenstapel etc will ich ja auch alles machen, kommt alles in die Mechanics rein. Die Grafik zeigt wirklich nur den ganz äußeren Aufbau 😄
Dass die Funktionen noch zu Klassen gehören, und die Werte zu Klassen gehören, hab ich jetzt nicht rein getan, ich wollte eigentlich nur verdeutlichen, wo welcher Zugriff benötigt wird 😄

5.299 Beiträge seit 2008
vor 14 Jahren

Bei deinem Plan habich gar kein Plan, wie anfangen.

wenn ich aber den Ablauf des Kartenspiels kapiert hab, kannich anfangen, mir Objekte zu basteln, die man dafür braucht.

Dann kann man gucken, dass sich die Objekte den Regeln entsprechend verhalten

Und dann überlegen, wie man das anzeigt.

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Die Objekte hab ich ja soweit sogar schon relativ fertig, alle in der Game-Klasse - mein einziges Problem soweit ist, dass ich immernoch nicht weiss, wie/wo ich jetzt optimalerweise ein Objekt davon erstelle, damit ichs auch nutzen kann ^^
Für die Anzeige haben wir auch schon eine Lösung gefunden, alles kein Problem 😃 Wie gesagt, das einzige Problem ist, dass ich es nicht schaffe, den Mechanics-Block (also das Game-Objekt) außerhalb des Input-Blockes (der Form) zu erstellen.

5.299 Beiträge seit 2008
vor 14 Jahren

Wie - alle Objekte in der Game-Klasse?

Jedes Objekt ist doch eine eigene Klasse, oder wie meinst du das?

Also ich würde meine Objekte als DataTables in einem typisierten Dataset anlegen. Von dem Dataset käme eines aufs Main-Form, und dann Gui-Programmierung, dass die User was mit die Dinger tun können.

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Die Instanzen der Klasse sind in der Gameklasse. Anders gesagt, die Gameklasse ist einfach eine Art Container für alles Relevante.

Angenommen ich würde jetzt einen Kartenstapel als Klasse haben. Wohin mit diesem Objekt, wenn nicht auf die Form? Genauso, wo kommen die anderen Sachen hin? Gut, nun habe ich, wie gesagt, die Dinger dort hingeschrieben, wo sie am nähesten gebraucht werden - in der Gameklasse. Aber wohin nun mit der?

5.299 Beiträge seit 2008
vor 14 Jahren

Ah, vermutlich wird sich die Game-Klasse auch ums Abspeichern kümmern müssen.
Du mußt nur aufpassen, dass du nicht das Rad neu erfindest, also eine Art typisiertes Dataset nachprogrammierst 😉

Aber wohin nun mit der? Na, aufs Form!

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Also das mit den Datasets ist schon ein guter Hinweis =) Werde ich mal drüber nachdenken, so ein Dataset für den Speicher in der Klasse zu nutzen. Aber trotzdem muss ja die Gameklasse noch erstellen, oder, wenn ich das Dataset als gleichstufiger Speicher zur Gameklasse sehe, diesen auch irgendwo hinlegen.
Aber gibt keine Möglichkeit, das außerhalb der Form zu tun? Komme ich irgendwann zwangsläufig immer dazu, es auf die Form zu packen, egal, wie oft ich das nun einpacke?
In Delphi hätte ich ja einfach eine einzige Globale Variable vom Typ Game erstellt und darein dann alles andere gekapselt. Denn wie bereits angesprochen, gehört auf die Form ja eigentlich keine Logik/Programmsteuerung. Die insgesamte Steuerungsinstanz läge hier aber dann doch wieder auf der Form - diese soll ja aber eigentlich nur als reines Eingabeinstrument dienen.
Ist da keine Möglichkeit, das Objekt dort zu erstellen, wo auch die Form erstellt wird, sodass diese auf gleicher Ebene sind?

[Rechts unmöglich, nur links?]

5.299 Beiträge seit 2008
vor 14 Jahren

Singleton wurde nun ja schon tausend mal erwähnt (gähn!).

Und warum tuts auf dem MainForm so weh?

Werde ich mal drüber nachdenken, so ein Dataset für den Speicher in der Klasse zu nutzen. Aber trotzdem muss ja die Gameklasse noch erstellen, oder, wenn ich das Dataset als gleichstufiger Speicher zur Gameklasse sehe, diesen auch irgendwo hinlegen.

Tja, sieht so aus, als dass an deinem Mechanix/Ausgabewerk - Konzept nix zu rütteln ist 😉 . Denn sieh man zu.

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Hmm, vielleicht seh ichs tatsächlich zu eng.
Ich hatte für Delphi immer im Kopf, auch aus dem Informatikunterricht (von dem ich nicht viel halte), dass die Form nur eine Schnittstelle zwischen User und Anwendung ist und steuernder Programmcode darin nichts verloren hat. Dazu zählten auch Klassen. Denn wenn ich das in der Klasse fest verankere, ist die Form ja elementar wichtig und kann nicht mehr jederzeit rausgenommen /ausgetauscht werden.
Ich hätte jetzt gedacht, das gehört zur OOP im Allgemeinen und ist in C# nicht anders 😕

Dass ich mich nicht von dem Konzept abwenden will, liegt daran, dass ich mir nicht ein Spiel überlegt habe und dann wie ich es gut umsetze, sondern zuerst das Konzept und dann nach was gesucht habe, was recht simpel ist und was sich darauf anwenden lässt. 😃
Nun gut, Singleton werde ich dann jetzt mal testweise versuchen zu implementieren.

Mein Fazit aus dem Topic wäre dann also, dass es nicht möglich ist, ein Objekt, ein Dataset oder irgendetwas anderes zu erstellen, ohne dass es irgendwann auf einem Grundtyp (Form, Konsole etc.) landet.
Ist das soweit richtig? =)

Ich danke schonmal für die viele Geduld mit mir 😄
fortuneNext

5.299 Beiträge seit 2008
vor 14 Jahren

Denn wenn ich das in der Klasse fest verankere, ist die Form ja elementar wichtig und kann nicht mehr jederzeit rausgenommen /ausgetauscht werden.

Du verankerst ja nicht das Form in der Klasse, sondern instanzierst die Klasse im Form.

Und wenn du halt ein neues Form willst, instanzierste die Klasse eben da.
Finde ich sogar voll modular.

gut, wennde die public Member der Klasse umbaust, wird das Form natürlich aua! schreien. Aber das Form müssteste eh dran anpassen.

Mein Fazit aus dem Topic wäre dann also, dass es nicht möglich ist, ein Objekt, ein Dataset oder irgendetwas anderes zu erstellen, ohne dass es irgendwann auf einem Grundtyp (Form, Konsole etc.) landet.
Ist das soweit richtig? =)

nö.

Wenn du einen Klassen-Member (Property, Field, event, method) als static deklarierst, gibts das Teil genau einmal, und ist keinem Objekt (also keiner Instanz der Klasse) zugeordnet.

Aber eiglich findnwa das garnicht schlecht, dass jedes Objekt in einem anderen Objekt enthalten ist, bis schließlich alles in einer lokalen Variable in Main() enthalten ist, denn da ist das ganze Programm drin.

Hier, ich spendir dir noch einen Singleton 😉:



namespace _Tests {
   public class Class2 {

      //Auf Instance kann von überall zugegriffen werden, mit var i = Class2.Instance;
      public static Class2 Instance = new Class2();

      //der private Konstruktor verhindert, dass von aussen eine weitere Instanz erstellt werden kann
      private Class2() { }

      //diese Property ist der aktuellen Class2-Instanz zugeordnet - aber es gibt ja nur eine
      //Zugriff also von überall: Class2.Instance.AProperty = "Hallo Wald!";
      public string AProperty { get; set; }
   }
}

Der frühe Apfel fängt den Wurm.

F
fortuneNext Themenstarter:in
45 Beiträge seit 2009
vor 14 Jahren

Okay, JETZT hats geklickt. Super, vielen Dank =) Ich verwende nun ein Dataset in meiner Klasse, die nun static ist. 😄
Vielen Dank für die Hilfe und Geduld sag ich dann mal 😃

fortuneNext