Domanda

Ho un'app WinForm CRUD abbastanza grande che ha numerosi oggetti. Persona, Iscrizione, Piano, CaseNote ecc. . Esistono oltre 30 moduli che compongono l'app con l'interfaccia utente suddivisa logicamente. Membro, Iscrizioni, Piani, Case Note, ecc. .

Sto cercando di capire come posso creare il mio Person Object dopo aver cercato nel Modulo di ricerca e passare l'oggetto al successivo modulo richiesto. Qualunque cosa possa essere, diciamo Dati demografici . In breve, ho bisogno che l'oggetto Person sia disponibile in tutta l'App e ce ne può essere solo uno.

Ora ho un'esposizione ZERO ai motivi di design ma ci sto provando. Ho letto http://www.switchonthecode.com/tutorials/csharp-tutorial -singleton-pattern e http://www.yoda.arachsys.com /csharp/singleton.html ma voglio essere sicuro di capire correttamente come applicare questo alla mia situazione.

Innanzitutto, gli esempi indicano che stai accedendo a un riferimento , giusto? Sbaglio o dovrei accedere al valore ?

Secondo, c'è qualcos'altro che devo fare per renderlo disponibile a livello globale? Devo solo dichiarare un'istanza su ogni modulo ma attraverso questo schema Singleton in modo da non avere più di uno?

Grazie

MODIFICA 1

Per chiarire, Tutti gli oggetti sono oggetti figlio di Persona. Inoltre, come sfugge alla pagina di ricerca; gli utenti possono selezionare un diverso CurrentPerson. Ma possono interagire solo con ONE alla volta.

Infine, come ho affermato che sono un bambino in questo e se dovessi considerare qualcos'altro, un approccio diverso, per favore, dillo e se tu fossi così gentile da offrire qualche spiegazione sul perché, sarei molto grato.

MODIFICA 2

Sulla base del commento di Medicine Man, ho pensato di chiarire.

Innanzitutto, grazie a tutti coloro che hanno contribuito finora. In secondo luogo, non conosco la prima cosa sui modelli di design e certamente non ho il più nebuloso se ne è necessario uno nella mia situazione attuale.

Se qualcuno ha un metodo migliore, più semplice o, secondo te, più appropriato di passare un oggetto dati da FORM a FORM a FORM, PER FAVORE, dillo.

Alla fine ho solo bisogno di un modo per tenere traccia delle informazioni mentre i miei utenti vanno da un posto all'altro. Grazie


È stato utile?

Soluzione

Puoi usare il modello Singleton per assicurarti che sia stata creata solo un'istanza.

Tuttavia, la giuria è ancora fuori (almeno nella mia mente ) se questa è una buona decisione. C'è molto da leggere su SO e altri luoghi su questo.

Mi avvicinerei a questo da un'angolazione diversa. Farei assumere tutte le mie forme in un'istanza Person nel costruttore. In questo modo, ogni modulo è sempre e solo preoccupato per l'istanza di Person.

Puoi farlo creando una nuova classe che eredita da Form e ha un campo / proprietà / costruttore per la tua persona. Quindi, qualsiasi modulo che utilizza Person può ereditare dalla tua nuova classe.

Dovresti, ovviamente, gestire la creazione del tuo oggetto Person. Potresti persino farlo con un singleton. Tuttavia, il vantaggio è che ogni modulo non deve sapere come creare una persona o chi ha creato la persona. In questo modo, se scegli di allontanarti dal Singleton modello , non dovresti cambiare tutti i tuoi riferimenti alla tua istanza singleton.

Modifica

Ecco un po 'di codice per dimostrarlo. Mi ci è voluto un po 'per convincere lo stilista a suonare bene. Ho dovuto aggiungere un costruttore privato vuoto in PersonForm per impedire al progettista di non generare un errore.

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 (aggiungi un'etichetta denominata 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;
    }
}

Altri suggerimenti

  

Innanzitutto, gli esempi indicano che stai accedendo a un riferimento, giusto? Sbaglio o dovrei accedere al valore?

La tua classe a cui stai accedendo è un riferimento a una singola classe in memoria. Ad esempio, supponiamo che la tua classe sia:

public class Person { ... }

Se ne hai un singleton, avrai una sola "Persona" salvato nella memoria, con un riferimento condiviso a quella persona nel singleton. Quando accedi alla tua singola persona, lavorerai con quel riferimento, che è probabilmente quello che vuoi. Qualsiasi modifica apportata alla persona la cambierà ovunque.

  

Secondo, c'è qualcos'altro che devo fare per renderlo disponibile a livello globale? Devo solo dichiarare un'istanza su ogni modulo ma attraverso questo schema Singleton in modo da non avere più di uno?

I singleton sono usati sostanzialmente per imporre che ogni volta che usi l'oggetto, è lo stesso oggetto (ogni uso è un riferimento separato a quello, singolo oggetto in memoria). Puoi semplicemente prendere il singleton ovunque ti serva e funzionerà.

Potresti fare qualcosa del genere:

public static class PersonController
{
    private static Person _Person;

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

        return _Person;
    }
}

Questo assicurerà che ci sia un solo oggetto persona. Riceverai un riferimento all'oggetto _Person, non una copia, quindi qualsiasi modifica riguarderà il singolo oggetto che ti aspetti.

Come dice Reed, i singoli impongono che lo stesso oggetto sia utilizzato in tutta l'applicazione. Tuttavia, dalla tua domanda non mi sembra che tu abbia la stessa istanza della classe persona disponibile nell'intera applicazione, poiché esiste il "modulo di ricerca" che sembra che ti permetta di cambiare la persona attualmente selezionata.

In questo caso potrebbe essere necessario che il tuo singleton sia una classe contenitore che contiene il contesto corrente dell'applicazione e quale persona è attualmente selezionata. Potrebbe essere qualcosa del tipo:

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() { }
}

(Nota che questo non è un modello singleton ideale poiché non è thread-safe ...)

Quindi il modulo di ricerca imposterà la persona attualmente selezionata con:

Context.Instance.CurrentlySelectedPerson = personSelectedInForm;

E i demografici di possono usarlo come:

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

Puoi anche usare il modello monostato con la tua classe Person .

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

Crea un oggetto monostato per 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; }
    }
}

Ora puoi inizializzare il monostato.

CurrentPerson.Person = GetPersonByUserInput();

Quindi utilizza le istanze CurrentPerson in tutto il codice e accederanno tutte a uno stato condiviso comune.

CurrentPerson currentPerson = new CurrentPerson();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top