1

まず、タイトルが私が言及しているものを正確に説明しているかどうかわからないので、これを何と呼ぶか​​についてコメントを残してください。または、担当者がいる場合は名前を変更してください。

たとえば、本と図書館の2つのクラスがあるとします。ライブラリには、所有するすべての書籍のリストであるプロパティが含まれています。ブックには、それが属するすべてのライブラリのリストであるプロパティがあります。

Bookには、ライブラリのリストからライブラリを削除するRemoveFromLibraryメソッドがあります。また、同じ方法でもう一方の端、つまり図書館が所有する本のリストをクリーンアップする必要があります。同じことがもう一方の端にも当てはまります。ライブラリのRemoveBookメソッドは、それを含むそのブックのライブラリのリストもクリーンアップします。

まず第一に、これは理にかなっていますか?コードを呼び出すのに、クリーンアップについて心配する必要がなく、1つの論理アクションを実行するために2つのメソッドを呼び出す必要がないのは便利なようです。つまり、一方のリストから削除しても、もう一方のリストから削除しても意味がありません。同時に、これはそれらをあまりにも緊密に結合していると言うことができますが、それが問題になった場合は、デカップリングするためにリファクタリングするだけだと思います。

これを実装する限り、私がよくわからないのは、通常のパブリックメソッドを呼び出すだけで、各メソッドが他のメソッドを呼び出す無限ループになるということです。クリーンアップしない別の内部プロパティ(C#で動作)を作成することもできますが、他の1つのメソッドからのみ呼び出されることを意図したメソッドでAPIを散らかしているように感じます。または、基になるコレクションを内部として公開することもできます。これは少し優れていますが、それでも理想的ではないようです。より良い解決策はありますか、それともこれら2つのうちのいずれかを使用する必要がありますか、それとも呼び出しコードがクリーンアップ自体を実行することを確認する必要がありますか?

4

1 に答える 1

1

多分これはうまくいくでしょう。他のクラスのメソッドを呼び出す前removeに、そのオブジェクトのリスト(本など)に、削除したいオブジェクトがまだ含まれていることを確認してください。

ところで、これは擬似コードのみです(コンパイルされない場合があります)

class Book
{
    Library[] libraries;

    void RemoveFromLibrary(Library lib)
    {
        libraries.remove(lib);
        if (IsInLibrary(lib) && lib.HasBook(this)) // prevents call-loop
            lib.RemoveBook(this);
    }

    bool IsInLibrary(Library lib)
    {
        return libraries.Contain(lib);
    }
}


class Library
{
    Book[] books;

    void RemoveBook(Book bk)
    {
        books.remove(bk);
        if (HasBook(bk) && bk.IsInLibrary(this)) // prevents call-loop
            bk.RemoveLibrary(this);
    }

    bool HasBook(Book bk)
    {
        return books.Contain(bk);
    }
}

編集:コメントに基づいてコードを修正しました...それを書いている間私は眠くなりました:P

于 2009-04-27T03:48:37.757 に答える