Frage

Ich habe eine ziemlich große CRUD WinForm-Anwendung, die zahlreiche Objekte hat. Person, Einschreibung, Plan, CaseNote etc . Es gibt über 30 Formen, die die App mit der Benutzeroberfläche aufgeschlüsselt logisch bilden. Mitglied, Einschreibungen, Pläne, CaseNotes, etc .

Ich versuche, herauszufinden, wie ich meine erstellen Person Object , nachdem auf der Suche Suchforum und das Objekt an die nächste übergeben angeforderten Form. Was auch immer das sein mag, sagen wir Demografie . Die kurze davon ist, dass ich die Person Objekt muß in der gesamten App verfügbar sein und es kann nur einen geben.

Jetzt habe ich ZERO Belichtungsmuster zu entwerfen, aber ich versuche. Ich habe http://www.switchonthecode.com/tutorials/csharp-tutorial -singleton-Muster und http://www.yoda.arachsys.com /csharp/singleton.html aber ich möchte sicherstellen, dass ich das richtig verstanden, wie diese auf meine Situation anzuwenden.

Zunächst geben die Beispiele, dass Sie eine zugreifen Referenz , richtig? Täusche ich mich oder brauche ich, um den Wert zugreifen?

Zweitens gibt es noch etwas, das ich tun muß dies global verfügbar zu machen? Ich erkläre ich nur eine Instanz auf jeder Form, aber durch dieses Muster Singleton, um nicht mehr zu haben, dann ein?

Danke

EDIT 1

Um zu klären, sind alle Objekte untergeordnete Objekte von Person. Da auch die Suchseite entzieht sich zu; die Benutzer können eine andere currentPerson wählen. Aber sie können nur mit ONE Person zu einer Zeit, in Wechselwirkung treten.

Schließlich ist, wie ich gesagt ich bin ein Kind in diesem und wenn ich etwas anderes in Betracht ziehen sollte, ein anderer Ansatz bitte sagen so, und wenn Sie so freundlich sein würden als eine Erklärung, warum anbieten zu können, würde ich mich sehr dankbar.

EDIT 2

Basierend auf Medicine Man Bemerkung Ich dachte, ich wauld klären.

Zuerst Vielen Dank an alle, die bisher beigetragen hat. Zweitens, ich weiß nicht, das erste, was über Design Patterns und ich habe sicherlich nicht die leiseste, wenn ein bestimmte in meiner aktuellen Situation benötigt wird.

Wenn jemand ein besseres hat, einfacher, oder, Ihre Meinung nach, eine passendere Methode ein Datenobjekt aus Form von vorbei bilden dann auf Formular Bitte erzählen.

Am Ende habe ich brauche nur einen Weg, um die Informationen der Verfolgung als meine Nutzer von Ort gehen zu platzieren. Vielen Dank, dass Sie


War es hilfreich?

Lösung

Sie können die Singleton-Muster verwenden, um sicherzustellen, dass nur eine Instanz jemals geschaffen wird.

Allerdings die Jury noch aus (zumindest in meinem Kopf ), ob dies eine gute Entscheidung ist. Es gibt viel zu lesen auf SO und anderen Orten darüber.

Ich würde nähert dies aus einem anderen Blickwinkel. Ich würde machen alle meine Formen in einer Person Instanz im Konstruktor. Auf diese Weise ist jede Form immer nur Sorgen um es Instanz von Person.

Sie können dies tun, indem Sie eine neue Klasse erstellen, die von Form erbt und hat ein Feld / Objekt / Konstruktor für Ihre Person. Dann kann jede Form, die Person verwendet, kann von Ihrer neuen Klasse erben.

Sie würde natürlich, haben die Erstellung Ihrer Person-Objekt zu verwalten. Man könnte sogar mit einem Singleton tun. Allerdings ist der Vorteil, dass jede Form muss nicht wissen, wie eine Person zu erstellen oder wer die Person erstellt. Auf diese Weise, wenn Sie href="https://stackoverflow.com/questions/474613/how-should-i-refactor-my-code-to-remove-unnecessary-singletons"> zum , würden Sie nicht gehen alle Ihre Verweise auf Ihre Singleton-Instanz ändern.

EDIT:

Hier ist ein Code, um dies zu demonstrieren. Es dauerte eine Weile, die Designer zu bekommen schön zu spielen. Ich hatte einen leeren privaten Konstruktor in PersonForm hinzuzufügen, um den Designer zu bekommen, um nicht einen Fehler aus.

Program.cs

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyDerivedForm(new Person { Name = "Hello World!" }));
        }
    }

Person.cs

public class Person
{
    public virtual string Name { get; set; }
}

PersonForm.cs

using System;
using System.Windows.Forms;

public class PersonForm : Form
{
    private readonly Person myPerson;

    protected virtual Person MyPerson 
    {
        get
        {
            return this.myPerson;
        }
    }

    private PersonForm()
    {
    }

    public PersonForm(Person person)
    {
        this.myPerson = person;
    }
}

MyDerivedForm.cs (fügen Sie ein Label namens label1)

public partial class MyDerivedForm : SingletonMadness.PersonForm
{
    public MyDerivedForm(Person person)
        : base(person)
    {
        InitializeComponent();
    }

    private void MyDerivedForm_Load(object sender, EventArgs e)
    {
        label1.Text = this.MyPerson.Name;
    }
}

Andere Tipps

  

Zuerst geben Sie die Beispiele, dass Sie einen Verweis zugreifen, richtig? Täusche ich mich oder ich würde den Wert zugreifen müssen?

Ihre Klasse, die Sie zugreifen, ist ein Verweis auf eine einzige Klasse im Speicher. Zum Beispiel, sagen, dass Ihre Klasse ist:

public class Person { ... }

Wenn Sie eine Singleton davon haben, haben Sie eine einzige „Person“ im Speicher abgelegt, mit einer gemeinsamen Referenz auf diese einer Person in der Singleton. Wenn Sie Ihre Einzelperson zugreifen, werden Sie mit dieser Referenz arbeiten, was wahrscheinlich ist, was Sie wollen. Alle Änderungen an der Person wird es überall ändern.

  

Zweitens gibt es noch etwas, das ich tun muß dies global verfügbar zu machen? Ich erkläre ich nur eine Instanz auf jeder Form, aber durch dieses Muster Singleton, um nicht mehr zu haben, dann ein?

Singletons verwendet werden, um im Grunde zu erzwingen, dass jedes Mal, wenn Sie das Objekt verwenden, es ist das gleiche Objekt (jede Nutzung ist eine separate Bezugnahme auf die einem, einzelnes Objekt im Speicher). Sie können nur die Singleton greifen überall Sie es brauchen, und es wird nur funktionieren.

Sie können etwas tun:

public static class PersonController
{
    private static Person _Person;

    public static Person GetPerson()
    {
        if (_Person == null)
            _Person = new Person();

        return _Person;
    }
}

Dadurch wird sichergestellt, gibt es nur eine Person Objekt. Sie werden einen Verweis auf das Objekt _Person bekommen, keine Kopie, so werden alle Änderungen an den einzelnen Objekt werden Sie erwarten.

Wie Reed sagt, erzwingen Singletons, dass das gleiche Objekt in der gesamten Anwendung verwendet wird. Doch aus Ihrer Frage sieht es nicht mir, wie Sie die gleiche Instanz der Person-Klasse haben Sie zur Verfügung in der gesamten Anwendung, da die „Suche Form“, die aussieht wie es Sie die aktuell ausgewählte Person zu ändern.

In diesem Fall Ihre Singleton benötigen eine Container-Klasse sein, der den aktuellen Kontext der Anwendung hält und welche Person ist zur Zeit ausgewählt. Dies kann etwas wie:

public class Context
{
   private static Context _instance;

   public static Context Instance
   {
       get
       {
           if (_instance == null)
           {
               _instance = new Context();
           }
           return _instance;
       }
   }

   public Person CurrentlySelectedPerson { get; set; }

   private Context() { }
}

(Beachten Sie, dass dieses Muster keine ideale Singleton ist, da es nicht sicher ist Thread ...)

Dann wird das Suchformular die aktuell ausgewählte Person eingestellt würde mit:

Context.Instance.CurrentlySelectedPerson = personSelectedInForm;

Und die demografische aus kann es wie verwenden:

//Get the demographics for the current person
ShowDemographics(Context.Instance.CurrentlySelectedPerson);

Sie können auch die monostate Muster mit Ihrem Personclass verwenden.

public class Person
{
    public Guid Id { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

Erstellen Sie ein monostate Objekt für Person.

public class CurrentPerson
{
    public static Person Person { get; set; }

    public Guid Id
    {
        get { return CurrentPerson.Person.Id; }
        set { CurrentPerson.Person.Id = value; }
    }

    public String FirstName
    {
        get { return CurrentPerson.Person.FirstName; }
        set { CurrentPerson.Person.FirstName = value; }
    }

    public String LastName
    {
        get { return CurrentPerson.Person.LastName; }
        set { CurrentPerson.Person.LastName = value; }
    }
}

Jetzt können Sie die monostate initialisieren.

CurrentPerson.Person = GetPersonByUserInput();

Und dann CurrentPerson Instanzen über den gesamten Code verwenden, und sie werden alle Zugriffe auf einen gemeinsamen genutzten Zustand.

CurrentPerson currentPerson = new CurrentPerson();
scroll top