在哪里创建课程

时间:2014-02-20 09:37:43

标签: c# inheritance

我正在尝试使用“facility”作为Class建模生产系统,并将一些子类建模为“Activity”。该工具只有一个名称作为参数(目前),我想创建一个类的实例,将该名称作为文本框的输入读取。由于“activity”继承了它的“父类”的属性,我将创建类“activity”的实例而不是它的父类。

问题在于我不知道在哪里创建类以及如何传递它,以便在我添加第一个子类“Workstation”时,我可以编辑我之前创建的相同“活动”的属性。

不幸的是,我现在还没有任何代码可以添加,但请告诉我,如果您有什么特别想看的话,我会尝试将其添加到帖子中。

顺便说一句,它是一个带有GUI的WinForm应用程序的形状,我正试图这样做。

1 个答案:

答案 0 :(得分:1)

这里有几点需要注意。首先,您将要使用Composite pattern来封装类之间的关系。 (对于那些不了解OP类型层次结构的人来说,它确实在工厂环境中非常有意义。有许多活动正在进行,可以分为工作站和更高级别的设施。 )

所以,你应该有一个基类Activity类(通过公开一系列子活动支持Composite模式),然后你的"级别" (例如FacilityWorkstation)将继承自Activity。这些类中的每一个都具有独特的属性。

应在各自的文件中创建以下类,例如: Activity.csFactory.csWorkstation.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.
    }
}

您当然可以在topLevelFactoryActivitiesMainForm 公开,并将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的答案。 (很抱歉推销我自己的答案,但我不想两次打出整个例子。请原谅我。:))