MonoState, Singleton или производные формы: лучший подход для приложения CRUD?
У меня есть довольно большое приложение CRUD WinForm, которое имеет множество объектов. Человек, Регистрация, План, CaseNote и т. Д. Существует более 30 форм, которые составляют приложение с логически разбитым интерфейсом. Участник, Зачисления, Планы, CaseNotes и т. Д.
Я пытаюсь выяснить, как я могу создать свой объект Person после поиска в форме поиска и передать объект в следующую запрошенную форму. Что бы это ни было, скажем, демография. Суть в том, что мне нужно, чтобы объект Person был доступен во всем приложении, и он может быть только один.
Теперь у меня нулевое воздействие на шаблоны проектирования, но я пытаюсь. Я прочитал http://www.switchonthecode.com/tutorials/csharp-tutorial-singleton-pattern и http://www.yoda.arachsys.com/csharp/singleton.html но хочу убедиться, что правильно понимаю, как применить это к моей ситуации.
Во-первых, примеры утверждают, что вы обращаетесь к ссылке, правильно? Я ошибаюсь или мне нужно получить доступ к значению?
Во-вторых, есть ли что-то еще, что мне нужно сделать, чтобы сделать это глобально доступным? Должен ли я просто объявить экземпляр в каждой форме, но через этот шаблон Singleton, чтобы не иметь больше одного?
Спасибо
РЕДАКТИРОВАТЬ 1
Чтобы уточнить, все объекты являются дочерними объектами человека. Кроме того, поскольку страница поиска ускользает от; пользователи могут выбрать другого текущего лица. Но они могут взаимодействовать только с ОДНОЙ личностью одновременно.
Наконец, как я уже говорил, я в этом младенец, и если мне следует подумать о чем-то другом, пожалуйста, скажите другой подход, и если вы будете так любезны, предложите какое-то объяснение, почему, я был бы очень благодарен.
РЕДАКТИРОВАТЬ 2
Основываясь на комментариях Медицинского Человека, я решил прояснить ситуацию.
Во-первых, спасибо всем, кто внес свой вклад. Во-вторых, я не знаю ничего о шаблонах проектирования, и, конечно, у меня нет ни малейшего сомнения, нужен ли определенный шаблон в моей текущей ситуации.
Если у кого-то есть лучший, более простой или, по вашему мнению, более подходящий метод передачи объекта данных из FORM в FORM в FORM, тогда ПОЖАЛУЙСТА, сообщите.
В конце концов мне просто нужен способ отслеживания информации, когда мои пользователи перемещаются с места на место. Благодарю вас
5 ответов
Вы можете использовать шаблон Singleton, чтобы обеспечить создание только одного экземпляра.
Тем не менее, жюри все еще отсутствует (по крайней мере, на мой взгляд), является ли это хорошее решение. Об этом много читают на SO и других местах.
Я бы подошел к этому под другим углом. Я заставил бы все мои формы взять экземпляр Person в конструкторе. Таким образом, каждая форма беспокоится только о своей личности.
Вы можете сделать это, создав новый класс, который наследуется от Form и имеет поле / свойство / конструктор для вашей персоны. Затем любая форма, использующая Person, может наследоваться от вашего нового класса.
Вам, конечно, придется управлять созданием объекта Person. Вы могли бы даже сделать это с помощью синглтона. Тем не менее, преимущество заключается в том, что каждая форма не должна знать, как создать человека или кто создал человека. Таким образом, если вы решите отойти от шаблона Singleton, вам не придется менять все ссылки на экземпляр Singleton.
РЕДАКТИРОВАТЬ:
Вот некоторый код, чтобы продемонстрировать это. Мне потребовалось некоторое время, чтобы заставить дизайнера играть хорошо. Мне пришлось добавить пустой закрытый конструктор в 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;
}
}
Во-первых, примеры утверждают, что вы обращаетесь к ссылке, правильно? Я ошибаюсь или мне нужно получить доступ к значению?
Ваш класс, к которому вы обращаетесь, является ссылкой на один класс в памяти. Например, скажем, ваш класс:
public class Person { ... }
Если у вас есть этот синглтон, у вас в памяти будет сохранен один "Персона" с общей ссылкой на этого человека в синглтоне. Когда вы получите доступ к своему единственному человеку, вы будете работать с этой ссылкой, что, вероятно, то, что вы хотите. Любые изменения в человеке изменят это везде.
Во-вторых, есть ли что-то еще, что мне нужно сделать, чтобы сделать это глобально доступным? Должен ли я просто объявить экземпляр в каждой форме, но через этот шаблон Singleton, чтобы не иметь больше одного?
Синглтоны используются для обеспечения того, чтобы каждый раз, когда вы используете объект, это был один и тот же объект (каждое использование - это отдельная ссылка на один, единственный объект в памяти). Вы можете просто взять синглтон где угодно, и он просто сработает.
Вы могли бы сделать что-то вроде этого:
public static class PersonController
{
private static Person _Person;
public static Person GetPerson()
{
if (_Person == null)
_Person = new Person();
return _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);
Вы также можете использовать шаблон моностата с вашим 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();