0

私は最新の MUD エンジンのプロトタイプを作成しています。MUD はシミュレーションの単純な形式であり、私が取り組んでいる概念をテストするための優れた方法を提供します。これにより、コード内のいくつかの場所が少し不明確になり、設計に問題が生じています (おそらく欠陥があるため)。私は最初にモデルを使用しており (これを変更する必要があるかもしれません)、ゲーム オブジェクトのトップダウン アーキテクチャを設計しました。私はこれを完全に間違っているかもしれません。

私が行ったことは、MUDObject エンティティを作成することです。このエンティティは、事実上、キャラクター、そのアイテム、人種など、他のすべての論理構造のベースです。また、属性、イベント、およびフラグと同様に、論理的な目的で使用される 3 つのメタ クラスのセットも作成しました。 . それらはかなり単純で、すべて 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();
    }
}

私は2つのことに興味があります。

  1. MUDObject から派生した型ごとに個別の ObjectSet を持つようにコンテキストを再コーディングする方法はありますか?

    • すなわち context.MUDObjects.Flags または context.Flags
    • そうでない場合、具体的に子タイプを照会するにはどうすればよいですか?
  2. 私が使用している Update/Pause/Resume/Stop アーキテクチャは、EF エンティティに直接配置した場合に正しく機能しますか? データのみを目的としているよりも与えられた?

    • ロックは問題になりますか?
    • 部分クラスは、変更が行われたときに自動的にコミットしますか?
    • フラット リポジトリを使用して、ゲーム エンジンで直接これを行う方がよいでしょうか?
4

2 に答える 2

2

1) MUDObject から派生した型ごとに個別の ObjectSet を持つようにコンテキストを再コーディングする方法はありますか?

はいあります。すべてのエンティティに対して基本クラスを定義する場合、エンティティ フレームワーク モデルの一部ではない抽象基本クラスを使用するのが一般的です。モデルには派生型のみが含まれ、コンテキストにDbSetは派生型の s が含まれます (それが の場合DbContext)

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

必要に応じて、クラス間の継承を実装できますが、それはポリモーフィズムを表現するためであり、一般的な永続性関連の動作を実装するためではありません。

2) 私が使用している Update/Pause/Resume/Stop アーキテクチャは、EF エンティティに直接配置すると正しく機能しますか?

いいえ。エンティティは持続性について何も知らないはずです。コンテキストは、それらの作成、変更の追跡、および更新/削除を担当します。変更を自動的にコミットすることについてのあなたの質問にも答えていると思います:いいえ。

詳細:

ここで、単一責任の原則を持ち出すのは良いことだと思います。一般的なパターンは

  • コンテキストにストアからオブジェクトを移入させる
  • オブジェクトをその責任に従って行動させる (シミュレーション)
  • 必要に応じてコンテキストに状態を保存させます

Pause/Resume/Stop は MUD オブジェクトの責任になると思います。更新は、まったく異なる種類のアクションと責任です。

今、私は推測しなければなりませんが、あなたのWorldクラスを受講してください。その責任を短いフレーズで表現できるはずです。たとえば、「他のオブジェクトをハーバードする」または「境界を定義する」などです。タイミングを合わせる必要はないと思います。タイミングは、時間間隔が経過したことを知らせるコアユーティリティの責任であるべきだと思います。他のオブジェクトはそれに応答する方法を知っています (たとえば、状態の変更を行うか、コンテキストまたはリポジトリが変更を保存します)。

まあ、これは考え方のほんの一例に過ぎず、おそらく正しくはありません

もう 1 つのことは、変更の保存は、シミュレーションを実行するオブジェクトの状態変更ほど頻繁に行うべきではないと考えていることです。おそらく、プロセスが劇的に遅くなるでしょう。おそらく、それはより長い間隔で、またはユーザーのアクションによって実行する必要があります。

于 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はこれで完全に機能します。正しくする必要があるだけです。

私が使用している Update/Pause/Resume/Stop アーキテクチャは、EF エンティティに直接配置した場合に正しく機能しますか? データのみを目的としているよりも与えられた?

この場合、ストラテジー パターンと呼ばれるデザイン パターンの使用を検討する必要があると思います。調査を行うと、オブジェクトに適合します。

ロックは問題になりますか?

システムをどのように開発するかによって異なります....

部分クラスは、変更が行われたときに自動的にコミットしますか?

その質問を理解していませんでした....部分クラスは通常のクラスと同じで、異なるファイルにあるだけですが、コンパイルすると(またはvshost.exeのためにデザイン時のイベント)、実際には1つにすぎません。

フラット リポジトリを使用して、ゲーム エンジンで直接これを行う方がよいでしょうか?

答えるのは難しいです。それはすべて、ゲームの要件、展開戦略に依存します....

于 2013-05-17T23:48:46.407 に答える