1

次のようにアーカイブシステムをコーディングしています。

IAchievement - すべての実績が実装する必要があるインターフェース

AchievementManager - ユーザー ID を使用してすべての実績をチェックするクラス

私の考えは、次のようなことを実行できるように、ArchivementManager で共有機能を持つことでした。

AchievementManager.checkUser(userId)

または

AchievementManager.check(userId, achievementId)

とにかく、AchivementManager は各 IAchievement 実装の関数チェックを呼び出す必要があります。

私がチェックしている各アチーブメントのインスタンスを持つことは意味がないので、チェックメソッドを共有/静的として宣言できると期待していました。したがって、AchievementManager 内で呼び出すことができます

AchivementXXX.check(userId)

しかし、インターフェイスで共有関数を宣言できません。

回避策はありますか?実績システムを実装するのは悪いアプローチですか?

編集:

これはゲーム用ではなく、ASP.NET の Web サイト用です

4

5 に答える 5

1

あなたのアプローチがインターフェイスを定義することである場合、はい、AchievementManager に関連する各実績タイプのインスタンスを保持させることは理にかなっています。

たとえば、さまざまなゲームの状態を追跡し、さまざまなゲームイベントをリッスンして、成果が達成されたことを検出できるようにするために、成果インスタンスが存在する必要があると予想されるため、これも理にかなっています。それ以外の場合、実績は Check メソッドをどのように実装しますか?

于 2012-12-18T08:37:06.957 に答える
0

インターフェイスと継承を使用しない方法もあります。

class Achievement {
    private Predicate<UserId> actualCheckUser;

    public bool CheckUser(UserID userId) {
        return actualCheckUser(userId);
    }

    public Achievement(Predicate<UserId> checkUser) {
        if (checkUser == null) {
            throw new ArgumentNullException("checkUser");
        }
        actualCheckUser = checkUser;
    }
}

アチーブメントのメソッドを呼び出して、ユーザーがそれを持っているかどうかを確認します。アチーブメントをタイプとして表す場合、アチーブメントのメソッドはタイプのメソッド、つまり静的メソッドです。ただし、インターフェイスに静的メソッドを含めることはできません。アチーブメントをオブジェクトとして表す場合、アチーブメントのメソッドは単純な古いオブジェクトのメソッドです。

ただし、Achievementクラスのインスタンスごとに、このメソッドの動作を変える必要があります。これを行う1つの方法は、実際、CheckUser抽象化してオーバーライドすることですが、アチーブメントごとに個別のクラスを宣言する必要があります。もう1つの方法は、デリゲートを使用することです。アチーブメントオブジェクトにプラグインするだけで、それだけです。内部的には、それも追加のクラスの作成につながります。

個人的には、どちらのデザインが優れているかはわかりませんが、タイプの観点からはメタプログラミングは、オブジェクトの観点からはOOPよりも難しいと思います。

于 2012-12-18T08:58:59.553 に答える
0

コメントに続いて、ここにいくつかのオプションがあります..

public class AchievementA : AchievementBase
{
  public void GetAchievementForAByUser(int userId)
  {
       base.CheckId(userId);
  }



 }

public class AchievementB : AchievementBase
 {

  }

 public class AchievementManager : IAchievement
{
    protected void CheckId(int userId)
{

}

}

あなたのインターフェイス IAchievement は、アチーブメントの各サブクラスで利用できるメソッドのコントラクトを実装します。

于 2012-12-18T08:46:18.253 に答える
0

インターフェイスをスーパークラス アチーブメントに実装し、そのクラスを MustInherit として宣言できます。したがって、すべての実績はスーパークラスから継承され、固有の部分をオーバーライドできます。チェックメソッドをオーバーライド不可に設定して、誰もそれをいじることができないようにすることができます

于 2012-12-18T08:41:52.340 に答える