Моностатейные, Одноэлементные или Производные Формы:Лучший подход к CRUD-приложению?

StackOverflow https://stackoverflow.com/questions/825617

Вопрос

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

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

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

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

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

Спасибо

ПРАВКА 1

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

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

ПРАВКА 2

Основываясь на комментарии Знахаря, я подумал, что должен уточнить.

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

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

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


Это было полезно?

Решение

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

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

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

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

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

Редактировать:

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

Program.cs Программа.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!" }));
        }
    }

Персона.cs

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

Форма лица.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;
    }
}

Другие советы

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

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

public class Person { ... }

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

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

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

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

public static class PersonController
{
    private static Person _Person;

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

        return _Person;
    }
}

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

Как говорит Рид, синглтоны обеспечивают, чтобы один и тот же объект использовался во всем приложении.Однако, судя по вашему вопросу, мне не кажется, что у вас есть один и тот же экземпляр класса 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);

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

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

Создайте объект monostate для 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();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top