我正在尝试使用“facility”作为Class建模生产系统,并将一些子类建模为“Activity”。该工具只有一个名称作为参数(目前),我想创建一个类的实例,将该名称作为文本框的输入读取。由于“activity”继承了它的“父类”的属性,我将创建类“activity”的实例而不是它的父类。
问题在于我不知道在哪里创建类以及如何传递它,以便在我添加第一个子类“Workstation”时,我可以编辑我之前创建的相同“活动”的属性。
不幸的是,我现在还没有任何代码可以添加,但请告诉我,如果您有什么特别想看的话,我会尝试将其添加到帖子中。
顺便说一句,它是一个带有GUI的WinForm应用程序的形状,我正试图这样做。
答案 0 :(得分:1)
这里有几点需要注意。首先,您将要使用Composite pattern来封装类之间的关系。 (对于那些不了解OP类型层次结构的人来说,它确实在工厂环境中非常有意义。有许多活动正在进行,可以分为工作站和更高级别的设施。 )
所以,你应该有一个基类Activity
类(通过公开一系列子活动支持Composite模式),然后你的"级别" (例如Facility
和Workstation
)将继承自Activity
。这些类中的每一个都具有独特的属性。
应在各自的文件中创建以下类,例如: Activity.cs
,Factory.cs
,Workstation.cs
:
class Activity
{
// An attribute that every Activity may need: a displayable name.
// This might be useful if you have a TreeView, e.g., showing all the activities.
public string Name { get; private set; }
// Every Activity could have child activities - this is the Composite pattern.
// You can loop through these to navigate through the hierarchy of your data.
// (This is often done using recursion; see example below with GetAllWorkstations().)
public List<Activity> ChildActivities { get; private set; }
public Activity()
{
ChildActivities = new List<Activity>();
}
public override string ToString() { return Name; }
}
class Factory : Activity
{
public string City { get; private set; }
public string Address { get; private set; }
}
class Workstation : Activity
{
public string WorkstationNumber { get; private set; }
}
然后必须在某处处理加载您的模型的责任。一个好的地方是你的主要形式。例如,您可以编写如下代码:
class MainForm : Form
{
private readonly List<Factory> topLevelFactoryActivities;
public MainForm()
{
// ... other code
topLevelFactoryActivities = LoadTopLevelFactoryActivities();
}
private IEnumerable<Factory> LoadTopLevelFactoryActivities()
{
var factories = new List<Factory>();
// TODO: Load the factories, e.g. from a database or a file.
// You can load all the child objects for each factory here as well,
// or wait until later ("lazy-loading") if you want to.
// NOTE: If this becomes complex, you can move the LoadTopLevelFactoryActivities()
// method to its own class, which then becomes your "data access layer" (DAL).
return factories;
}
}
现在,如果您想查找属于特定工厂的所有工作站,您可以在Factory
类上编写如下方法:
class Factory : Activity
{
// ... other code
public IEnumerable<Workstation> GetAllWorkstations()
{
return GetWorkstationsRecursive(this);
}
private IEnumerable<Workstation> WorkstationsIn(Activity parentActivity)
{
foreach (var workstation in parentActivity.ChildActivities.OfType<Workstation>)
{
// Uses a C# feature called 'iterators' - really powerful!
yield return workstation;
}
foreach (var childActivity in parentActivity.ChildActivities)
{
// Using recursion to go down the hierarchy
foreach (var workstation in WorkstationsIn(childActivity))
{
yield return workstation;
}
}
}
}
你会这样称呼它,例如在你的主要形式:
class MainForm : Form
{
// ... other code
public MainForm()
{
// ... other code
// Assume this is assigned to the factory that you want to get all the workstations for
Factory myFactory;
var workstations = myFactory.GetAllWorkstations();
// Now you can use 'workstations' as the items source for a list, for example.
}
}
作为示例用例,您可能希望显示第二个表单(属于主表单),该表单显示所有工作站的列表。 (在实践中,您可能不应该创建太多窗口;更喜欢构建一个不重叠的布局。但只是为了展示如何绕过模型实例...)
class WorkstationListForm : Form
{
private IEnumerable<Workstation> workstations;
public WorkstationListForm(IEnumerable<Workstation> workstations)
{
this.workstations = workstations;
//TODO: You can now use 'workstations' as the ItemsSource of a list view in this form.
}
}
您当然可以在topLevelFactoryActivities
上MainForm
公开,并将this
的变量MainForm
传递给{{} 1}}构造函数。然后您可以像WorkstationListForm
那样访问MainForm
上的成员:
public WorkstationListForm(MainForm mainForm)
{
var topLevelFactoryActivities = mainForm.topLevelFactoryActivities;
// Now WorkstationListForm has full access to all the data on MainForm. This may or
// may not be helpful (it's usually best to minimize sharing and public fields).
}
其次,您希望在视图(用户界面代码/类)和模型(活动层次结构)之间使用适当的分隔。
第三,如果将任何类型的实时数据推送到用户界面,那么只要模型发生变化,您就需要一个数据绑定机制来自动更新视图。
一般来说,#2&amp; #3通过Model-View-ViewModel模式得到普遍解决。有一个很好的tutorial here for building an MVVM app using WinForms/C#。
这应该让你开始,至少。另请参阅similar question的答案。 (很抱歉推销我自己的答案,但我不想两次打出整个例子。请原谅我。:))