Laden...

Von allen Klassen auf zentrales Objekt zugreifen können

Erstellt von Rob D vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.792 Views
R
Rob D Themenstarter:in
34 Beiträge seit 2008
vor 15 Jahren
Von allen Klassen auf zentrales Objekt zugreifen können

Also folgendes ich blicke da noch nicht so ganz durch. Ich möchte gern in meiner main Funktion, eine Klassen namens Applikation instanzieren. Dort sollen sachen wie username usw. gespeichert werden. Da die main der oberste aufruf in der Hierarchie ist bleibt das Objekt Applikation am leben. Ich möchtet nun in allen Klassen( mit z.b. Applikation.Username ) auf die Variablen in Applikation zugreifen. Glaube mit Vererbung klappt das nicht ganz weil ich in From klassen dann nicht drauf zu greifen kann. Ich hoffe nicht das ich das objekt immer mit Schleifen muss. Danke

4.207 Beiträge seit 2003
vor 15 Jahren

=> Singleton (Design Pattern)

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

2.187 Beiträge seit 2005
vor 15 Jahren

Hallo,

Bevor du eine "Application" Klasse anlegst, solltest du dir es zwei mal überlegen. Statische Variablen (und was anderes ist das nicht) waren schon zu C-Zeiten verpönt. 😉
Außerdem müsste deine "Application" Klasse alle anderen Klassen und Rollen (für die Klassen/Objekte) kennen, die jemals in deiner Software auftauchen, damit man die richtigen Properties anlegen kann.
Außerdem könntest du die Properties nicht richtig Schützen (Prinzip der Kapselung), die Properties müssten alle einen öffenltichen Getter und Setter haben, und damit können Sie von überall gesetzt werden und nicht nur von den Klassen, die für das Property zuständig sind (z.B. könnte jede Maske den Angemeldeten Benuzter ändern und nicht nur die Anmelden-Maske).

Aber um auch eine (oder zwei) mögliche Lösungen zu nennen:

In der User-Klasse ein Statisches Property und eine "Anmelden" Methode.


public class User
{
  privaet static readonly object _Lock = new object();
  private static User _AngemledeterUser;
  public static User AngemeldeterUser
  {
    get{lock(_Lock){return _AngemeldeterUser;}}
  }
  public static void Anmelden(string username, string password)
  {
    lock(_Lock)
    {
       // hie eine Prüfung durchführen und das richtige User-Objekt hohlen.
       _AngemeldeterUser = erkannterUser;
       OnAngemeldeterUserChanged();
     }
  }
  private static void OnAngemeldeterUserChanged()
  {
    lock(_Lock)
    {
      EventHandler event = AngemeldeterUserChanged;
      if(event!=null)
        event(typeof(User),EventArgs.Empty);
    }
  }
  public static event EventHandler AngemeldeterUserChanged;
}

Oder eine Anmledung-Klasse mit einem "Singelton"-Pattern:


pulbic class Anmeldung : INotifyPropertyChanged
{
  private Anmeldung(){}

  privaet static readonly object _Lock = new object();
  private static Anmeldung _Instanz = new Anmeldung();
  public static User Instanz
  {
    get{lock(_Lock){return _Instanz;}}
  }
  public static void Anmelden(string username, string password)
  {
    lock(_Lock)
    {
      Instanz.Anmelden(username,password);
    }
  }

  public virtual void Anmelden(string user, string password)
  {
    // wieder user suchen
    if(!userGefunden) throw new SecurityException();
    else
    {
      this.AnmeldeZeitpunkt = DateTime.Now; // hier kann man dann auch wieder Events auslösen und so weiter.   
    }
  }
}

Gruß
Juy Juka

R
Rob D Themenstarter:in
34 Beiträge seit 2008
vor 15 Jahren

Welcher der o.g. Methoden ist jetzt die bessere. Oder wie sollte man das lösen das man ind jeder Klasse auf den Username zugreifen kann?

Gelöschter Account
vor 15 Jahren

JuyJuka lösungist auch ein singleton(habs nur kurz überflogen aber es sieht sehr dannach aus).

demnach sind beide lösungen richtig^^

2.187 Beiträge seit 2005
vor 15 Jahren

Hallo,

@JAck30lena: Die zweite Lösung "Anmeldung" ist ein Singelton. Die Erste ist kein Singelton.

@Rob D: Welche Lösung am besten ist, kann man nicht sagen. Viel hängt auch von den eigenen Vorlieben ab.

  • Soll alles, was mit dem User zu tun haben in der User-Klasse stehen?
  • "Eine Klasse = Eine Aufgabe"?
    Ich persönlich würde, z.B.: meine erste Variante "User" benutzen, da so alles für die User-Steuerung in einer Klasse ist.
    Aber sicher kann ich dir von einer "Application"-Klasse abraten (siehe in meinem ersten Post).

Gruß
Juy Juka

R
Rob D Themenstarter:in
34 Beiträge seit 2008
vor 15 Jahren

ich brauche das weil ich in verschiedenen From Klassen auf die Logindaten, die am Anfang eingeben habe. Wie kann ich nun dann in den anderen Klasen auf den Singelton zugreifen

Gelöschter Account
vor 15 Jahren

klassenname.instanz.zugriffsmethode

K
80 Beiträge seit 2006
vor 15 Jahren

Vorsicht: Die instanz des oben beschrieben singletons wird beim ersten Zugriff auf die Klasse ( egal ob eine statische methode die public ist oder nicht ) erstellt. Ich persönlich bevorzuge folgendes:



  private static volatile Anmeldung _Instanz;
  public static User Instanz
  {
    get{
		lock(_Lock){
			if(_Instanz == null)
				_Instanz = new Anmeldung();
			return _Instanz;
		}
	}
  }

Hier wird erst wenn der User das objekt wirklich braucht das Objekt erstellt. Zusätzlich sollte der statische Instanz Member mit volatile gekennzeichnet werden.

Gelöschter Account
vor 15 Jahren

warum volatile?

K
80 Beiträge seit 2006
vor 15 Jahren

volatile stellt sicher, dass im feld immer der aktuelle wert vorhanden ist. Die felder werden nicht von Compileroptimierungen erfasst usw.. Generell gillt: Felder auf die von mehreren threads zugegriffen werden kann und die von mehreren threads geändert werden können, werden volatile gekennzeichnet.

Gelöschter Account
vor 15 Jahren

ja aber das alles machst du doch mit dem lockobject zunichte. deswegen meine frage warum hier volatile.

K
80 Beiträge seit 2006
vor 15 Jahren

schau in der msdn nach der C# Singleton Beispiel implementierung, das ist einfacher als wenn ich das hier jetzt repliziere

1.200 Beiträge seit 2007
vor 15 Jahren

Also, the variable is declared to be volatile to ensure that assignment to the instance variable completes before the instance variable can be accessed.

http://msdn.microsoft.com/en-us/library/ms998558.aspx

Aha. Der Compiler könnte sonst Optimierungen durchführen und das Objekt freigeben bevor es fertig initialisiert ist.

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

K
80 Beiträge seit 2006
vor 15 Jahren

Das hab ich ja schon geschrieben, dass die member aus der compiler optimierung ausgeschlossen wird 😉

Edit: Der compiler gibt nichts frei, der GC gibt frei und der wurde damit nicht angesprochen, es wird lediglich sichergestellt, dass das Feld zugewiesen ist (read != null) bevor darauf zugegriffen wird.

Gelöschter Account
vor 15 Jahren

erhm:

schau in der msdn nach der C# Singleton Beispiel implementierung, das ist einfacher als wenn ich das hier jetzt repliziere

ich zitiere mal die msdn dazu:

Der volatile-Modifizierer wird normalerweise für ein Feld verwendet, auf das mehrere Threads zugreifen, ohne dass die lock-Anweisung (C#-Referenz)-Anweisung zur Zugriffsserialisierung verwendet wird.

das macht ja auch sinn... da die lockanweisung nur noch sequenziellen zugriff erlaubt.

O
778 Beiträge seit 2007
vor 15 Jahren

um nochmal den Unterschied zwischen den beiden Implementierungen von JuyJuka aufzugreifen: Ich meine, der Unterschied liegt in der Auffassung.

Die erste Variante liefert den Benutzer, die zweite die Anmeldung. während der Benutzer nur Benutzerdaten speichert und die Anmeldung statisch ist, ist bei der Anmeldung das Verfahren der Anmeldung flexibel. Erstere Variante lässt also Rückschlüsse zu, dass der aktuelle User beispielsweise garantiert seinen Benutzernamen und sein Passwort angeben musste, damit diese Daten dann mit einer Benutzerdatenbank abgeglichen werden kann. Das User-Objekt ist damit vertrauenswürdig, weil ich genau weiß, wie es entstanden ist.

Bei der zweiten Variante sind theoretisch auch Anmeldungen möglich, die einfach nur sagen "Hallo, ich bin der Admin und darf alles". Entscheidend ist hier die Instanzierung der Anmeldung. Vorteil ist natürlich der, dass man, wenn man das Anmeldungsobjekt nicht statisch instanziert, sondern von einer Factory produzieren lässt, die Art und Weise der Anmeldung sehr einfach variieren kann. Wenn man also mehrere Arten der Authentifizierung parallel haben will, dann ist das eigentlich das Mittel der Wahl, aber man muss der Factory vertrauen können. Wenn diese nicht gut abgesichert ist öffnet man damit Tür und Tor für Angreifer, die sich sehr einfach als Admins ausgeben können - oder man misstraut dem User-Objekt.