C# 以命令模式保存系统

C# 以命令模式保存系统,c#,unity3d,coroutine,strategy-pattern,saving-data,C#,Unity3d,Coroutine,Strategy Pattern,Saving Data,我在Unity c#中为员工保存任务时遇到问题。我将它们的任务像命令模式一样实现,并将方法(协同路由)作为任务算法。现在我必须将他们的任务保存到磁盘上,稍后再加载以恢复它们 例如: 任务接口: interface IEmployeeTask { IEnumerator PerformTask(); } employee.cs ... public WorkOnTask(IEmployeeTask task) { this.currentTask = task; Star

我在Unity c#中为员工保存任务时遇到问题。我将它们的任务像命令模式一样实现,并将方法(协同路由)作为任务算法。现在我必须将他们的任务保存到磁盘上,稍后再加载以恢复它们

例如:

任务接口:

interface IEmployeeTask
{
    IEnumerator PerformTask();
}
employee.cs

...
public WorkOnTask(IEmployeeTask task)
{
    this.currentTask = task;
    StartCoroutine(task.PerformTask());
}
...
两个任务实现:

class SomeTask1 : IEmployeeTask
{
    ...
    public SomeTask1(int someImportantParameter){...}

    public override IEnumerator PerformTask
    {
        assignedEmployee.GoThere();
        yield return new WaitUntil(() => assignedEmployee.ReachedDestination);
        assignedEmployee.DoThis();
        yield return new WaitUntil(() => assignedEmployee.DidThis);
        assignedEmployee.UseParameter(someImportantParameter);
    }

}
我无法重新启动这些任务,因此仅通过new或Activator创建任务并分配引用不会有帮助


我可以创建一个save类并将抽象的
TaskSave-IEmployeeTask.GetSave()
IEmployeeTask.LoadFrom(TaskSave-save)
,为每个任务实现一个类,其中包含一些丑陋的
public readonly int-referenceId
,但如果有机会,我可以避免创建所有这些类并保持代码干净,我很想知道这是否可能。

在阅读了下面的评论后,我知道了什么:

首先,我应该将更复杂的TAK划分为单个原子
步骤
的结构,其中包含整个任务中当前步骤的数据。然后保存当前正在运行的任务和步骤以及执行该任务所需的数据


接下来必须有一个工厂,它知道如何使用保存的数据中的当前步骤重新创建任务。

为什么不能重新启动任务?您不能再次调用
start例程(task.PerformTask())
?我理解你的问题有点困难。这是关于在会话之间将任务保存到磁盘以供使用,还是说在会话期间暂停任务时保存为?我无法重新启动它,因为如果任务中的某项操作要执行两次或更多次,那将是愚蠢的。我必须从外部保存它,然后重新创建tasks状态。再想一想,您的案例是不同的,因为您使用的是委托,您将无法序列化它。也许要构造任务,可以使用反射和外部文件(方法列表)动态运行委托?给你更广阔的竞争环境。即使将委托排队并从外部获取/保存int索引(state)也可以(但这样做会丢失沿途的引用)。一个简单的答案是用单独的对象表示各个步骤,然后将它们序列化为JSON。然后,创建一个可以构建任务的工厂。在我看来,你把这件事复杂化了。您希望保存有关任务的数据,而不是有关其行为的数据。如果您有
步骤
对象,那么
任务
对象可以是
步骤
的数组和指向当前步骤的
整数。整个结构是可序列化的,关键是将行为方面与数据驱动方面分开。任务中的任务或步骤仍然可以由协同程序启动,但任务或步骤的状态由数据定义(而不是其行为);可以对其进行序列化和反序列化。工厂的职责可能是反序列化保存的任务,重新创建状态并返回完整的任务对象。然后,
PerformTask
方法可以简单地检查必须运行哪个步骤,类似于我前面的评论。
class SomeTask2
{
    ...
    public SomeTask2(SomeClass someImportantReference){...}

    public override IEnumerator PerformTask
    {
        IThinkYouKnowWhereThisIsGoing();
        LemmeJustUseSomeObject(someImportantReference);
        yield break;
    }
}