2015-09-17 4 views
7

異種オブジェクトの複雑なツリーをナビゲートする最適な方法は何ですか?たとえば

class Vehicle { 
    Collection<Axle> axles; 
} 

class Axle { 
    Collection<Wheel> wheels; 
} 

class Wheel { 
    // I think there are dually rims that take two tires -- just go with it 
    Collection<Tire> tires; 
} 

class Tire { 
    int width; 
    int diameter; 
} 

私は私が知っているすべての車両オブジェクトのコレクションを取得することができ、それを通してサービスを提供しています。今私は、特定の幅と直径のタイヤを持っていると私はそれを取ることができる車両を見つけるしたいと言います。単純な方法はそうのように、4つのネストされたループのセットを持つことです。

for (Vehicle vehicle : vehicles) { 
    for (Axle axle : vehicle.getAxles()) { 
     for (Wheel wheel : axle.getWheels()) { 
      for (Tire tire : wheel.getTires()) { 
       if (tire.width == targetWidth 
       && tire.diameter == targetDiameter) { 
        // do something 
        break; 
       } 
      } 
     } 
    } 
} 

は、このための良いデザインパターンがありますか?または、使用するより良いデータ構造ですか?車にマッピングされたタイヤ情報のどこかのインデックスを保持する方が良いでしょうか?

編集:コメント

からの質問に答えるあなたがサービスから受け取ったデータの構造を制御することがありますか?

はい

あなたは、同じデータに異なるタイヤに対して複数回検索する必要がありますか?

はい

パフォーマンスが問題ですか?

ない特に

あなたはタイヤを見つけた場合、あなたはそれが含まれている車両を知る必要がありますか、また、車軸とホイールが必要なのですか?時には、ちょうど車

、時々ちょうど車軸 - 二つの異なるコンテキスト

あなたが発見されたタイヤへの参照が必要ですか?

はい、私は車軸

EDIT2必要がある場合には: は、上記2つのコンテキストを説明するために、さらにメタファーの拡張:

コンテキスト1 - 私が知りたいです車両を回収して戻すことができます

状況2 - 私は仕事をしようとしている車両にいるので、車軸とタイヤを知りたい

+0

それが依存...あなたは持っていますかサービスから受け取るデータの構造を制御できますか?同じデータで複数のタイヤを何度も検索する必要がありますか?パフォーマンスは問題ですか?タイヤを見つけたら、どの車にそれが入っているかを知る必要がありますか、車軸と車輪も必要ですか?見つかったタイヤのリファレンスが必要ですか? – Cinnam

+0

私は郵便で回答しました。見てくれてありがとう! –

+0

この問題は、デメテルの法則(「法律」よりも原則です)に関連しているように見えます。 http://stackoverflow.com/q/12284057/1168342 – Fuhrmanator

答えて

2

Java 8 streamsを使用してループをフラット化できます。

vehicles.stream() 
    .flatMap(vehicle -> vehicle.getAxles().stream()) 
    .flatMap(axle -> axle.getWheels().stream()) 
    .flatMap(wheel -> wheel.getTires().stream()) 
    .filter(tire -> tire.width == targetWidth 
      && tire.diameter == targetDiameter) 
    .forEach(tire -> { 
     // do something 
    }); 

流れのいいところは、など、あなたがfilter追加を挿入することができることであるfilterfindAny、どこかのシーケンスではかなり簡単に呼び出します。

+0

タイヤが見つかったとき、またはクラスで親参照が必要なときに、車両とアクスルにアクセスできますか? – Cinnam

+0

@Cinnam - それほど見えません - 私は車のサンプル用のテストアプリケーションを作成しましたが、forEachブロックのコードはタイヤ上のものを参照できませんでした。 –

0

あまりにも多くのアイテムやパフォーマンスが大きな問題でない限り、おそらくネストされたループ(またはJohnの回答からのストリーム)に行きます。

あなたは、検索のための2つのコンテキストを持っているので、あなたが検索方法に適切なアクションを渡すことができます - (この場合はループを使用して)このような何か:

interface TireAction { 
    void doSomething(Vehicle v, Axle a, Tire t); 
} 

void findTireAndPerform(int targetWidth, int targetDiameter, TireAction action) { 
    for (Vehicle vehicle : vehicles) { 
     for (Axle axle : vehicle.getAxles()) { 
      for (Wheel wheel : axle.getWheels()) { 
       for (Tire tire : wheel.getTires()) { 
        if (tire.width == targetWidth && tire.diameter == targetDiameter) { 
         action.doSomething(vehicle, axle, tire); 
         break; 
        } 
       } 
      } 
     } 
    } 
} 

void someMethod() { 
    ... 

    findTireAndPerform(width, diameter, (v, a, t) -> { 
     // send worker to 'v' 
    }); 

    ... 

    findTireAndPerform(width, diameter, (v, a, t) -> { 
     // work on 'a' and 't' 
    }); 
} 
+0

ええ、私はそれについてもっと研究して考えると、もっとループを維持することを考えています。それは、しかし、ランクされます。 –

+0

@SamJonesまあ、それは最高のものではないかもしれない:)しかし、この場合、私はそれが不適切だとは思わない。 – Cinnam

1

あなたのデータ構造を変更せずに、あなたは」勝ちました重要な違いを生むことができます。あなたはラムダでいくつかの構文的な砂糖を加えることができますが、それは本質的に同じ解決策です。あなたが見て可能性が

もの:

  • あなたのモデルはゼロ車軸または百とVehiclesすることができます。それはあなたのビジネスモデルに依存しますが、それは変だと思われます。
  • あなたのモデルでは、異なる車軸、異なる車輪を持つことができます。本当に必要ですか?モデルのどの要素が個別の識別情報(現在は各オブジェクトに含まれています)を持ち、単なる値オブジェクトであるべきかを確認してください。
  • 本当にそのような詳細なモデルが必要かどうかを確認してください。現在、内部オブジェクトのコレクションのみを保持する2つのクラス(AxleWheel)があります。それらがgetAllInnerTypes()という単純なJavaBeanオブジェクトである場合は、このクラスの削除を検討する必要があります。タイヤ情報がほぼ直接Vehicleクラスに格納されるべき場合もあります。
私はあなたのロジックを反転し、もちろんあなたは、私が個人的に厚いオブジェクトへとそれらを包むだろう、その場合には(他の理由のための薄いあなたのオブジェクトを保持したい場合を除き、 Vehicleに質問を移動する
2

ここからは、ビジネスロジックのこの部分があなたのドメイン全体にどの程度重要かによって、いくつかの可能性があります。

  1. 複数のアクションがある場合は、サンプルで行ったように繰り返すことができます。あるいは私が提案したのと同じ方法で、質問を正しいコンポーネントに続けてください。あなたがこれを行う時間の複雑さと一緒に暮らすことができる限り、それは問題ないはずです。
  2. このチェックでは、通常、あなたは、あなたが直接車両に保持するタイヤの種類への参照を持つことができないだろう、これはあなたのTireコレクションのいずれかである、またはVehicleを構築するときにTireSpecificationインスタンスを渡すことができ、何かの場合何らかの理由であなたはこれらが分離保つために必要がある場合は(あなたの意図は、車のタイヤや収まることができるもののほんのスペックの問題で非常に明確ではない?)
関連する問題