我有一个相当大的CRUD WinForm应用程序,它有很多对象。 人员,注册,计划,案例注释等。应用程序中有超过30种表单,逻辑上分解了UI。 会员,注册,计划,CaseNotes等。
我想在搜索表单上搜索并将对象传递给下一个后,想办法如何创建 人物对象 要求的表格。无论那是什么,让我们说人口统计。缺点是我需要在整个应用程序中使用Person对象,并且只能有一个。
现在我对设计模式有零接触,但我正在尝试。我已阅读http://www.switchonthecode.com/tutorials/csharp-tutorial-singleton-pattern和http://www.yoda.arachsys.com/csharp/singleton.html,但我想确保我正确理解如何将此应用于我的情况。
首先,示例说明您正在访问引用,对吗?我错了还是需要访问值?
其次,还有什么我需要做的才能使全球可用吗?我只是在每个表单上声明一个实例,但通过这个Singleton模式,以便没有多于一个吗?
由于
澄清一下,所有对象都是Person的子对象。此外,正如搜索页面所躲避的那样;用户可以选择不同的currentPerson。但他们一次只能与 ONE 人进行互动。
最后,正如我所说,我是一个婴儿,如果我应该考虑其他事情,请说明一个不同的方法,如果你愿意提供一些解释,为什么,我会非常感激。
基于Medicine Man的评论我认为我已经澄清了。
首先,感谢迄今为止做出贡献的所有人。 其次,我不知道关于设计模式的第一件事,如果在我目前的情况下需要某个模型,我肯定没有最模糊的。
如果某人有一个更好,更简单,或者在您看来,更合适的方法将数据对象从FORM传递到FORM到FORM,那么请告诉。
最后,我需要一种跟踪信息的方法,因为我的用户从一个地方到另一个地方。 谢谢
答案 0 :(得分:2)
首先,示例说明您正在访问引用,对吗?我错了还是需要访问该值?
您正在访问的类是对内存中单个类的引用。例如,假设您的班级是:
public class Person { ... }
如果你有一个单身,你将在内存中保存一个“人物”,并在单身人士中共享一个人。当您访问单个人时,您将使用该引用,这可能是您想要的。对此人的任何更改都会在任何地方进行更改。
其次,还有什么我需要做的才能使全球可用吗?我只是在每个表单上声明一个实例,但通过这个Singleton模式,以便没有多于一个吗?
Singletons基本上强制执行每次使用对象时,它都是相同的对象(每次使用都是对内存中单个对象的单独引用)。你可以在你需要的任何地方抓住单身人士,它只会起作用。
答案 1 :(得分:1)
你可以这样做:
public static class PersonController
{
private static Person _Person;
public static Person GetPerson()
{
if (_Person == null)
_Person = new Person();
return _Person;
}
}
这将确保只有一个人物对象。您将获得对_Person对象的引用,而不是副本,因此任何更改都将是您期望的单个对象。
答案 2 :(得分:1)
您可以使用Singleton模式确保只创建一个实例。
然而,the jury is still out(至少在我看来)是否这是一个好的决定。 SO和其他地方有很多关于此的阅读。
我会从不同的角度来看待这个问题。我将所有表单都放在构造函数中的Person实例中。这样,每个表单只会担心它的Person实例。
您可以通过创建一个继承自Form的新类来实现此目的,并为您的Person提供字段/属性/构造函数。然后,任何使用Person的表单都可以从您的新类继承。
当然,您必须管理Person对象的创建。你甚至可以用单身人士来做这件事。但是,好处是每个表单不必知道如何创建Person或创建Person的人。这样,如果您选择move away from the Singleton pattern,则不必更改对单例实例的所有引用。
修改强>
这里有一些代码来证明这一点。我花了一段时间才让设计师玩得很开心。我必须在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;
}
}
答案 3 :(得分:1)
正如里德所说,单身人士强制要求在整个应用程序中使用相同的对象。但是,从您的问题来看,它并不像我在整个应用程序中拥有相同的人员类实例,因为有“搜索表单”,它可以让您更改当前选定的人员。
在这种情况下,您的单例可能需要是一个容器类,它包含应用程序的当前上下文以及当前选择的人员。这可能是这样的:
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);
答案 4 :(得分:0)
你也可以在你的Person
类中使用monostate模式。
public class Person
{
public Guid Id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
}
为Person
构建一个monostate对象。
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; }
}
}
现在你可以初始化monostate。
CurrentPerson.Person = GetPersonByUserInput();
然后在整个代码中使用CurrentPerson
个实例,它们都将访问一个共同的共享状态。
CurrentPerson currentPerson = new CurrentPerson();