0

0..n 個のオブジェクトがあり、それぞれが一意の識別子を必要とし、次のように作成されます。

public class Squirrel {

    private static numSquirrels = 0;

    private String id = null;

    public Squirrel() {
        this(String.valueOf(numSquirrels++);
    }

    public Squirrel(String id) {
        this.id = id;
    }
}

これはいくつかの点で問題ですが、1 つ挙げておきます。

単体テストの場合、numSquirrels 変数はテスト間で引き継がれます。これは、異なる集団のリスを扱っている場合でも同じです。これは、最初からやり直したいときに ID が増え続けることを意味します。

  • これは、SquirrelFactory (子供たちが絶賛しているもの) を使用する適切な時期ですか?
  • 依存性注入を使用して Factory を Squirrel オブジェクトに渡す必要がありますか、それとも Squirrel クラスを、外部とのインターフェースを持つ Squirrel Factory 内に含める必要がありますか?
  • ユーザーが ID を設定できるようにする (または少なくとも ID を提案する) ことができるようにする場合、一意性を確保するにはどうすればよいですか?
4

6 に答える 6

3

この実装は問題なく動作すると思いますが、同時実行性を扱う場合はおそらく AtomicInteger を使用する必要があります。

単体テストの問題は、モックと別のクラスにラップしてモックすることを組み合わせて使用​​ して解決できます。この投稿を参照してください JMockを使用してJavaで静的変数をモックする方法

または、簡単な解決策は、静的変数のセッターを公開することです。これにより、テスト ケースの最後に、変数を 0 に戻すか、「リセット」が意味するものは何でも設定できます。

于 2013-02-07T19:05:42.553 に答える
0

Squirrelファクトリとして機能するというクラスを導入しSquirellPopluation、静的カウンターをそのクラスに移動して、インスタンス変数にします。

ファクトリのユーザーが独自のIDを設定できるようにする場合は、単なるカウンターではなくセットを使用します。

于 2013-02-07T19:03:01.580 に答える
0

すべての要件を満たすには、新しいIDを取得し、それらがすべて一意であることを確認するためにSquirrelFactoryクラスが必要になると思います。おそらく、SquirrelFactoryをシングルトンにしたいと思うでしょう。

SquirrelFactoryの責任は次のとおりです。

  • 使用中のIDを追跡する
  • カウンターに基づいて新しいIDでリスを作成します(そしてそれが一意であることを確認してください)
  • 指定されたIDでリスを作成し(ファイルからロードする場合)、IDがすでに使用されている場合は、上記のような新しいものを作成します
  • 使用中のIDのリストに新しいリスのIDを追加します。
  • テストのために、おそらくカウンターとIDのリストをリセットする方法が必要です
  • (オプション)リスが削除されたときにリストからIDを削除する方法があります
于 2013-02-07T20:29:45.280 に答える
0

リス クラスはおそらく factory について知らないはずです。次の実装をお勧めします。

public interface Squirrel // interface, not class
{
    public String getID ();

    // other methods here
}

public class SquirrelFactory
{
    private int nextSquirrelID = 0;

    public Squirrel createSquirrel ()
    {
        return new SquirrelImpl (String.valueOf (nextSquirrelID++));
    }

    private static class SquirrelImpl implements Squirrel
    {
        private final String id;

        // other fields here

        public SquirrelImpl (String id)
        {
            this.id = id;
        }

        @Overrides
        public String getID ()
        {
            return id;
        }

        // other methods here
    }
}

次に、コンストラクターの代わりにcreateSquirrela のメソッドを使用します。SquirrelFactory単体テストごとに、SquirrelFactoryクラスの新しいインスタンスを作成します。

于 2013-02-07T19:13:10.687 に答える
0

クラスの静的な「リセット」メソッドを持つことができます。テストの分解 (またはセットアップ) の一部として呼び出します。

于 2013-02-07T19:05:53.937 に答える
0

最後の質問に関連する特定のケース:

ユーザーが ID を設定できるようにする (または少なくとも ID を提案する) ことができるようにする場合、一意性を確保するにはどうすればよいですか?

これを行うには、すべてのインスタンスを追跡する必要があります。BitSetたとえば、を使用できます。これを行うと、一種のデコンストラクタをコールドで提供します。

/**
 * Eat the squirrel.<br>
 * You can not do anything anymore with the squirrel after it has been eaten,
 * but it can be reborn.
 */
public void eat() { //at least, sounds friendlier than kill, shoot, or whatever
  instances.clear(id);
}

これは C++ のような実際のデコンストラクタではないため、注意してください。オブジェクトを (簡単に) 破壊することはできません。まだまだ使えます。その場合、これを内部で処理する必要があります。

ヒント: マルチスレッド コードを使用すると、ライブが複雑になります。しかし、どうやら静的IDから、そうではありません。

于 2013-02-07T19:25:02.567 に答える