MonoState, Singleton или производные формы: лучший подход для приложения CRUD? - PullRequest
4 голосов
/ 05 мая 2009

У меня довольно большое приложение CRUD WinForm, в котором есть множество объектов. Персона, Регистрация, План, CaseNote и т. Д. . Существует более 30 форм, которые составляют приложение с логически разбитым интерфейсом. Участник, Зачисления, Планы, CaseNotes и т. Д. .

Я пытаюсь выяснить, как я могу создать свой объект Object после поиска в форме поиска и передать объект в следующую запрошенную форму. Что бы это ни было, скажем Демография . Суть в том, что мне нужно, чтобы объект Person был доступен в приложении, и он может быть только один.

Теперь у меня НУЛЕВОЕ воздействие на Шаблоны проектирования, но я пытаюсь. Я прочитал http://www.switchonthecode.com/tutorials/csharp-tutorial-singleton-pattern и http://www.yoda.arachsys.com/csharp/singleton.html, но хочу убедиться, что правильно понимаю, как применить это к моей ситуации.

Во-первых, примеры утверждают, что вы обращаетесь к ссылке , правильно? Я ошибаюсь или мне нужно получить доступ к значению ?

Во-вторых, нужно ли что-то еще, чтобы сделать это глобально доступным? Должен ли я просто объявить экземпляр в каждой форме, но через этот шаблон Singleton, чтобы не иметь больше одного?

Спасибо

РЕДАКТИРОВАТЬ 1

Чтобы уточнить, все объекты являются дочерними объектами человека. Кроме того, поскольку страница поиска ускользает от; пользователи могут выбрать другого текущего лица. Но они могут взаимодействовать только с ONE Person одновременно.

Наконец, как я уже говорил, я в этом младенец, и если мне следует подумать о чем-то другом, пожалуйста, скажите другой подход, и если вы будете так любезны, объясните, почему, я бы очень благодарен.

РЕДАКТИРОВАТЬ 2

Основываясь на комментариях Медицинского Человека, я думал, что уточню.

Во-первых, спасибо всем, кто внес свой вклад. Во-вторых, я не знаю ничего о шаблонах проектирования, и, конечно, у меня нет ни малейшего сомнения, нужен ли определенный шаблон в моей текущей ситуации.

Если у кого-то есть лучший, более простой или, по вашему мнению, более подходящий метод передачи объекта данных из FORM в FORM в FORM, тогда ПОЖАЛУЙСТА, сообщите.

В конце мне просто нужен способ отслеживать информацию, как мои пользователи перемещаются с места на место. Спасибо


Ответы [ 5 ]

2 голосов
/ 05 мая 2009

Во-первых, примеры утверждают, что вы обращаетесь к ссылке, правильно? Я ошибаюсь или мне нужно получить доступ к значению?

Ваш класс, к которому вы обращаетесь, является ссылкой на один класс в памяти. Например, скажем, ваш класс:

public class Person { ... }

Если у вас есть этот синглтон, у вас в памяти будет сохранен один «Человек» с общей ссылкой на этого человека в синглтоне. Когда вы получите доступ к своему единственному человеку, вы будете работать с этой ссылкой, что, вероятно, то, что вы хотите. Любые изменения в человеке изменят его повсюду.

Во-вторых, нужно ли что-то еще, чтобы сделать это глобально доступным? Должен ли я просто объявить экземпляр в каждой форме, но через этот шаблон Singleton, чтобы не иметь больше одного?

Синглтоны используются для обеспечения того, чтобы каждый раз, когда вы используете объект, это был один и тот же объект (каждое использование - это отдельная ссылка на один единственный объект в памяти). Вы можете просто взять синглтон где угодно, и он просто сработает.

1 голос
/ 05 мая 2009

Как говорит Рид, синглтоны обеспечивают использование одного и того же объекта во всем приложении. Однако из вашего вопроса мне не кажется, что у вас есть один и тот же экземпляр класса person, доступный во всем приложении, поскольку есть «форма поиска», которая выглядит так, как будто вы можете изменить текущего человека.

В этом случае ваш синглтон, возможно, должен быть контейнерным классом, который содержит текущий контекст приложения и какой человек в настоящее время выбран. Это может быть что-то вроде:

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

(Обратите внимание, что это не идеальный шаблон синглтона, так как он не безопасен для потоков ...)

Тогда форма поиска установит для текущего выбранного человека:

Context.Instance.CurrentlySelectedPerson = personSelectedInForm;

И демографический от может использовать это как:

//Get the demographics for the current person
ShowDemographics(Context.Instance.CurrentlySelectedPerson);
1 голос
/ 05 мая 2009

Вы можете использовать шаблон Singleton, чтобы обеспечить создание только одного экземпляра.

Однако, жюри все еще отсутствует (по крайней мере, на мой взгляд) о том, является ли это правильным решением. Об этом много говорится на SO и в других местах.

Я бы подошел к этому под другим углом. Я бы заставил все мои формы принимать экземпляр Person в конструкторе. Таким образом, каждая форма беспокоится только о своей личности.

Вы можете сделать это, создав новый класс, который наследуется от Form и имеет поле / свойство / конструктор для вашего Person. Затем любая форма, использующая Person, может наследоваться от вашего нового класса.

Вам, конечно, придется управлять созданием вашего объекта Person. Вы могли бы даже сделать это с помощью синглтона. Тем не менее, преимущество заключается в том, что каждая форма не должна знать, как создать человека или кто создал человека. Таким образом, если вы решите отойти от шаблона Singleton , вам не придется менять все ссылки на ваш экземпляр Singleton.

EDIT:

Вот код, демонстрирующий это. Мне потребовалось некоторое время, чтобы заставить дизайнера играть хорошо. Мне пришлось добавить пустой закрытый конструктор в PersonForm, чтобы конструктор не выдавал ошибку.

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 (добавить метку с именем 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;
    }
}
1 голос
/ 05 мая 2009

Вы можете сделать что-то вроде этого:

public static class PersonController
{
    private static Person _Person;

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

        return _Person;
    }
}

Это обеспечит наличие только одного объекта. Вы получите ссылку на объект _Person, а не на копию, поэтому любые изменения будут относиться к ожидаемому объекту.

0 голосов
/ 05 мая 2009

Вы также можете использовать шаблон monostate с вашим классом Person.

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

Создание моностатического объекта для 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; }
    }
}

Теперь вы можете инициализировать моностат.

CurrentPerson.Person = GetPersonByUserInput();

А затем используйте CurrentPerson экземпляры по всему коду, и все они получат доступ к общему общему состоянию.

CurrentPerson currentPerson = new CurrentPerson();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...