0

我一直在为现代 MUD 引擎创建原型。MUD 是一种简单的模拟形式,并提供了一种很好的方法来测试我正在研究的概念。这导致我在我的代码中有几个地方有些不清楚,并且设计受到质疑(可能是由于它存在缺陷)。我首先使用模型(我可能需要更改它)并且我设计了一个自上而下的游戏对象架构。我可能做错了。

我所做的是创建一个 MUDObject 实体。这个实体实际上是我所有其他逻辑结构的基础,例如角色、他们的物品、种族等。我还创建了一组三个元类,它们用于逻辑目的以及属性、事件和标志. 它们相当简单,并且都继承自 MUDObject。

MUDObject 类旨在为所有对象提供默认数据行为,包括删除死对象。自动清理地板。等等。如果需要,这也旨在虚拟地促进这种逻辑。例如,检查房间以查看效果是否已结束并删除效果(删除标志)。

public partial class MUDObject
{
    public virtual void Update()
    {
        if (this.LifeTime.Value.CompareTo(DateTime.Now) > 0)
        {
            using (var context = new ReduxDataContext())
            {
                context.MUDObjects.DeleteObject(this);
            }
        }            
    }

    public virtual void Pause()
    {

    }

    public virtual void Resume()
    {

    }

    public virtual void Stop()
    {

    }        
}

我还有一个 World 类,它派生自 MUDObject 并包含区域和房间(其中又包含游戏对象)并处理用于运行更新的操作的计时器。(可能会被移动,把它放在这里好像它会限制它只有当时世界上的物体。)

public partial class World
{
    private Timer ticker;


    public void Start()
    {
        this.ticker = new Timer(3000.0);
        this.ticker.Elapsed += ticker_Elapsed;
        this.ticker.Start();
    }

    private void ticker_Elapsed(object sender, ElapsedEventArgs e)
    {
        this.Update();
    }

    public override void Update()
    {
        this.CurrentTime += 3;
        // update contents
        base.Update();
    }

    public override void Pause()
    {
        this.ticker.Enabled = false;
        // update contents
        base.Pause();
    }

    public override void Resume()
    {
        this.ticker.Enabled = true;
        // update contents
        this.Resume();
    }

    public override void Stop()
    {            
        this.ticker.Stop();
        // update contents
        base.Stop();
    }
}

我对两件事感到好奇。

  1. 有没有办法重新编码上下文,以便它为从 MUDObject 派生的每种类型具有单独的 ObjectSet?

    • 即 context.MUDObjects.Flags 或 context.Flags
    • 如果不是,我该如何专门查询子类型?
  2. 直接放入 EF 实体时,我正在使用的更新/暂停/恢复/停止架构是否正常工作?给出的比它仅用于数据目的?

    • 锁定会成为问题吗?
    • 部分类在进行更改时会自动提交更改吗?
    • 使用平面存储库并直接在游戏引擎中执行此操作会更好吗?
4

2 回答 2

2

1) 有没有办法重新编码上下文,以便它为从 MUDObject 派生的每种类型具有单独的 ObjectSet?

就在这里。如果您决定要为所有实体定义一个基类,通常会有一个不属于实体框架模型的抽象基类。模型仅包含派生类型,上下文包含DbSets 派生类型(如果是 a DbContext),例如

public DbSet<Flag> Flags { get; set; }

如果合适,您可以实现类之间的继承,但这将是为了表达多态性,而不是实现常见的与持久性相关的行为。

2) 当直接放入 EF 实体时,我使用的更新/暂停/恢复/停止架构是否正常工作?

不。实体不应该知道任何关于持久性的事情。上下文负责创建它们、跟踪它们的更改以及更新/删除它们。我认为这也回答了您关于自动提交更改的问题:不。

阐述:

我认为在这里提出单一责任原则很好。一般的模式是

  • 让上下文从商店中填充对象
  • 让对象根据自己的职责行事(模拟)
  • 让上下文在必要时存储它们的状态

我认为暂停/恢复/停止可能是 MUD 对象的职责。更新是一种完全不同的行动和责任。

现在我必须推测,但要上你的World课。你应该能够用一句话来表达它的责任,也许是“隐藏其他对象”或“定义边界”之类的东西。我认为它不应该做时机。我认为时间应该是一些核心实用程序的责任,它表明时间间隔已经过去。其他对象知道如何响应(例如,做一些状态更改,或者上下文或存储库,保存更改)。

好吧,这只是一个如何思考的例子,可能远非正确。

另一件事是,我认为保存更改不应像执行模拟的对象的状态更改那样频繁。它可能会大大减慢这个过程。也许应该以更长的时间间隔或通过用户操作来完成。

于 2013-05-17T23:43:56.293 回答
0

首先要说的是,如果您使用的是 EF 4.1(因为它被标记),您应该真正考虑使用 5.0 版(您需要为此创建一个 .NET 4.5 项目)

通过对性能的多项改进,您还可以从其他功能中受益。我将向您展示的代码适用于 5.0(我不知道它是否适用于 4.1 版本)

现在,让我们向您提出几个问题:

有没有办法重新编码上下文,以便它为从 MUDObject 派生的每种类型具有单独的 ObjectSet?如果不是,我该如何专门查询子类型?即 context.MUDObjects.Flags 或 context.Flags

是的你可以。但是调用有点不同,你不会有 Context.Worlds 你只会有这样调用的基类,如果你想获得 Worlds 的集合(从 MUDObject 继承,你会调用:

var worlds = context.MUDObjects.OfType<World>();

或者您可以通过使用泛型直接进行:

var worlds = context.Set<World>();

如果您以正确的方式定义继承,您应该有一个名为 MUDObjects 的抽象类,并且所有其他类都应该从该类继承。EF 可以完美地处理这个问题,你只需要让它正确。

直接放入 EF 实体时,我正在使用的更新/暂停/恢复/停止架构是否正常工作?给出的比它仅用于数据目的?

在这种情况下,我认为您应该考虑使用称为策略模式的设计模式,做一些研究,它会适合您的对象。

锁定会成为问题吗?

取决于你如何开发系统......

部分类在进行更改时会自动提交更改吗?

不明白那个问题.... 部分类就像普通类一样,它们只是在不同的文件中,但是在编译时(或在设计时的事件,因为 vshost.exe)它们实际上只是一个。

使用平面存储库并直接在游戏引擎中执行此操作会更好吗?

很难回答,这完全取决于游戏的要求,部署策略......

于 2013-05-17T23:48:46.407 回答