1

PHP コードの問題を解決しようとしていますが、これは他のコードでも解決できていないものでもあります。

1 つだけのコレクションに属さなければならないオブジェクトがあります。そして、主にコレクションの観点からこれらのオブジェクトにアクセスします。他のコードは、コレクションを経由せずにオブジェクトを見つけることは期待されません。

したがって、私が過去にこれを処理した方法は、オブジェクトにコレクションへの参照を与えることでした。このようにして、オブジェクトが 1 つのコレクションにのみ属することができることを満足させようとします。次に、オブジェクトをコレクションに追加します。

public function __construct(Collection $c)
{
    $this->setCollection($c);
}

public setCollection(Collection $c)
{
    $this->collection = $c;
    $c->addObject($this);
}

これは「Don't Repeat Yourself」と明らかに矛盾しています。そして、オブジェクトのコレクションに簡単にアクセスする必要があることと、オブジェクトが 1 つのコレクションにのみ属していることを必要とすることの要件が互いに矛盾するために発生します。オブジェクトはコレクション内にあることを認識し、コレクションはオブジェクトがコレクション内にあることを認識します。どちらかが同期しなくなると、システムが壊れます。

そして、あるコレクションから別のコレクションにオブジェクトを移動するコードを作成しようとすると、問題が明らかになります。または、オブジェクトを削除するとき。

では、この種の問題の解決策を見つけた人はいますか? 何か試してみるべきことがありますか?最終的には、多くの二重チェックで機能させることができますが、もっと良い方法が必要なようです.

4

1 に答える 1

1

「ダブルチェック」の最終ゲームまでのあなたの推論に従うかどうかはわかりません...しかし、このようなコードの何が問題なのですか?

class Collection {

   public function AddMember(Member $m) {
       $m->SetCollection($this);
       // add to underlying data structure
   }

   public function RemoveMember(Member $m) {
       // remove from underlying data structure
   }
}

class Member {
    private $collection = null;

    public function SetCollection(Collection $c) {
        if($this->collection)
            $this->collection->RemoveMember($this);
        $this->collection = $c;
    }

    public __destruct() {
        if($this->collection)
            $this->collection->RemoveMember($this);
    }
}

構文はおそらくオフです。テストされていない疑似コードとして扱い、必要に応じて参照を使用し、その他の免責事項などを使用してください。

これは、フレンド クラス/メソッドが適切なカプセル化に役立ち、コレクション オブジェクト以外の誰かがそのコレクションからメンバーを設定または削除するのを防ぐ優れた設計パターンです。また、どのメソッドをエントリ ポイントとして使用するかをじっくりと検討し、再帰ループに陥ることなく適切な処理を行う必要があります。このようなフレームワーク/ライブラリ クラスの場合、単体テストを行うと作業がはるかに簡単になります。

ifええ、基本的に追加、削除、または破棄を行う前に、チェックを行う必要があることを心配している場所がわかります。しかし、それがスマートで安全なポインター/参照パターンの性質です。DRY の原則は、安全性チェックの冗長性を回避することではなく、データの複数のコピーやアルゴリズムの冗長な実装を回避することを目的としています。はい、私の疑似コードの各メソッドは技術的にはアルゴリズムですが、ここでいくつかのことを噛み砕きます (わかりました、それらは実際には同じようなものであり、異なる観点から述べられています)。

  1. それらは一定の時間で実行されます (前述の再帰の落とし穴を回避する場合)。
  2. 真剣に:これまでで最短のアルゴリズム。
  3. ifライブラリ内のステートメントの半分を最適化することを心配している場合は、(1 つの) ツリーのフォレストが不足しています。最適化の時間は、コードを使いやすく、保守しやすくし、アルゴリズムの複雑さを軽減することに費やされます。一定時間アルゴリズムほど複雑ではありません。
  4. if追加または削除のたびに余分なステートメントを実行して、プロセッサを釘付けにするつもりはありません。O(n^2)大きなn. _

要約すると、安全な二重リンクされたデータ構造を実装するためのより良い方法は実際にはありません。各リンクの安全性を確認する必要があり、それがその方法です。

于 2013-05-02T21:03:53.040 に答える