4

オブジェクト Car を含むクラス ライブラリを開発しています。

ジレンマは、車自体が登録番号などのフィールドを持つクラスになり、車に関するその他の一般的な情報になることです。

しかし、車にはエンジンやシャーシなどがあります。これらのオブジェクトもモデル化する必要があります。それらは車に埋め込まれたクラスであるべきですか? そうでない場合、埋め込みクラスの使用シナリオは何ですか?

コンポジションは「の一部」であることを学んだので、別のクラスをモデル化し、たとえば車のフィールド レベルでエンジン タイプを使用してこれを実現できます。ただし、ctor で渡されるタイプとの「has a」関係である「aggregation」も適用されます (車にはエンジン「has an」)。

どちらに行けばいいですか?

編集:私は現在宿題をしているので、私からの返信がありません。クラス ライブラリは、自動車に基づく Web アプリ用です。私はプロの開発者です (私は生計を立てるために .NET で開発していますが、ジュニアとして)、これは宿題の質問ではありません。

ありがとう

4

7 に答える 7

4

それは本当にあなたのアプリケーションに依存します。

たとえば、ホイールを個別のクラスとして実装し、どのタイヤが装着されているか、どの程度摩耗しているかなどの情報を含めることができますが、アプリがホイールを気にしない場合、クラス全体がコードの無駄になります。

コンポジションの 3 つの使用例を見ることができます。

  • 所有クラスが複雑になりすぎているため、分割する必要があります。
  • 所有クラスには、クラスにマップできる一連のプロパティの複数のコピーがあります。これにより、これらすべてのプロパティをまとめてバインドできます。
  • 含まれているオブジェクトは、それを所有するオブジェクトとは別に検査または検討する必要がある場合があります (たとえば、Engine オブジェクトを別の車に移動したい場合)、または単一のユニットとして置き換える場合があります。

要約すると、複雑さをカプセル化するため、または繰り返しを排除するためのツールとして構成を使用します。これらの目的のいずれにも役立たない場合、おそらく新しいクラスを作成する価値はありません。

于 2009-12-16T07:54:57.827 に答える
4

クラスの責任はできるだけ少なくし、他の機能をカプセル化して他のクラスに委譲する必要があります。1 つのことを行う小さくて単純なクラスがたくさんあるということは、コードベースが読みやすく安定していることの証です。

はい、車にはエンジンが「あります」が、これと同様の「ある」関係にはインターフェースを使用することをお勧めします。繰り返しになりますが、教授によっては、工場にさまざまな車を作成させることでボーナス ポイントを獲得できる場合があります (適切ですよね?)。

public class Car
{
    private Engine engine;
    public Car(Engine engine)
    {
        this.engine = engine;
    }

    public void accelerate()
    {
        this.engine.goFaster();
    }

    public void decelerate()
    {
        this.engine.goSlower();
    }

}

public interface Engine
{
    public void goFaster();
    public void goSlower();
}


public class ReallyFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes really fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class NotAsFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes not as fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class CarFactory()
{
    public static Car createFastCar()
    {
         return new Car(new ReallyFastEngine());
    }

    public static Car createNotAsFastCar()
    {
         return new Car(new NotAsFastEngine());
    }
}
于 2009-12-16T15:47:32.193 に答える
2

宿題なので、家庭教師/教授/教師の好みによっては、エンジン、ホイールなどのクラスを個別に作成するルートをたどった方がよいでしょう。完全にオーバーエンジニアリングされている可能性があり、アプリケーションがそれらを気にしない場合でも、宿題が次のような標準によってマークされる可能性があります。

「彼らはエンジンクラスを識別しましたか」

「Start() のような実用的なメソッドはありますか」

「すべてを 1 つの大きなクラスにまとめると、実際にはより単純になります。なぜなら、彼らは構成を明らかに理解していないからです」

または、このスレッドのより実用的な人々が自分のデザインに適用する標準の種類ではありません。

于 2009-12-16T12:50:59.570 に答える
2

車のモデルのみを分解して、車の範囲外の個別のエンティティとして公開します。それについて考える別の方法は、キーを回したときに車がどのように始動するかを本当に理解していますか? 典型的なドライバーに関する限り、ボンネットの下にあるものはすべて 1 つの大きな (そしてうるさい) ブラック ボックスです。自動車エンジニアは、車の所有者によるメンテナンスが必要な一般的な部品を知っており、オイル ディップスティックやクーラント リザーバーのリフィル キャップなど、さまざまなレベルのユーザー インタラクション用に明示的に設計しています。

車の各パーツをモデル化できますか? もちろん。個々のスパーク プラグをモデル化することは役に立ちますか? おそらくそうではありません。

色やサイズなど、さまざまな属性の車が必要ですか? 乗客や牽引能力など、さまざまな機能を備えた車が必要ですか? 異なる 1 つの場所は、異なる動作の車が必要な場合です。これは、反応時間のような単純なものから攻撃性のような複雑なものまで、属性を持つ Driver オブジェクトのモデル化について本当に考える必要があるところです。

オブジェクト指向や継承の例として車両をモデル化することには問題があります。その例では、クラスを定義する重要な属性間の真の違いが実際には説明されていないからです。これは StackOverflow にとって新しいものではありませんが、この質問も重複していません 。この SO スレッドを参照してください。私はこれと同じ議論を友人と行い、そのログをブログに投稿しました。FAA が認識しているさまざまな航空機のタイプと、各タイプの規制がどのように細分化されているかをお読みください。航空機にはさまざまな種類がありますが、最大の違いは動力付きと動力なしの違いです。

FAA で使用されている定義を確認してください。

航空機とは、空中を飛行するために使用される、または使用されることを意図した装置を意味します。

飛行機とは、翼に対する空気の動的な反応によって飛行中に支えられる、空気より重いエンジン駆動の固定翼航空機を意味します。

飛行船とは、操縦可能なエンジン駆動の空気より軽い航空機を意味します。

空気より軽いものと空気より重いものもあります。熱気球は動力がなく、空気より軽いです。飛行船は動力があり、空気より軽いです。グライダーは動力がなく、空気より重いです。ボーイング 757 は動力付きで空気より重いですが、別のカテゴリーの「固定翼」を追加します。これは、同様に動力付きで空気より重いが「回転翼」であるヘリコプターとは異なります。

最初の 4 つを表形式で示します。

                 |  Powered   |    Unpowered
---------------------------------------------------
Lighter-than-air |  Blimp     |    Hot-air balloon 
Heavier-than-air |  737       |    Glider

あなたは絵を手に入れます。

エンジンを車とは別にモデル化するとは言えません。エンジンのない車はまったく別の動物になる可能性があるからです。エンジンのない車は、トレーラーのようなものではありません。これらの場合、「is-a」も「has-a」も、オブジェクトを構築する具体的な方法には適合しません。飛行船が空気より軽い航空機であるとは宣言しません。熱気球もそうです。それらが両方とも空気より軽いという事実は、それらが利用する物理学を除いて、何らかの形でそれらを関連させるものではありません. 適用される規則や規制が異なるため、この区別は重要です。別の角度から言えば、私たちは飛行船を「エンジンを搭載した」熱気球とは言いません。航空機は物理的に関連していませんが、

オブジェクトをその詳細レベルまで定義する必要がない場合は、オブジェクトをその詳細レベルまでモデル化する必要もないかもしれません。

于 2009-12-16T21:57:51.003 に答える
0

車は最上位の階層オブジェクトになります。番号、ID、説明などの単純なフィールドを含みます。また、それ自体がオブジェクトであるEngineのような複雑なフィールドがあります。

したがって、車は次のようになります。

class Car{
     String ID;
     Engine engine;
}

それは持っている-関係。

于 2009-12-16T08:03:53.027 に答える
0


エンジン、シャーシなどのクラスを内部クラス (組み込みクラス) として存在させる必要があるかどうかを判断する基準の 1 つは、
これらのクラスのインスタンスをアプリケーションの他の場所で使用できるかどうかです。このような場合、
決定は簡単で、これらのクラスを
(内部クラスとしてではなく) 個別に存在させることです。

これらのクラスがアプリケーションの他の場所で使用されていない場合でも、他の
基準はテスト可能性です。これらのクラスを内部および設計に組み込むことで、 コードを適切にテストして適切なカバレッジを提供
できる単体テストを作成できます。

たとえば、
Engine オブジェクトを参照するインスタンス変数を作成し、この変数が Car.And のコンストラクターで初期化されている場合
、Engine クラスにはテストが必要なメソッドがいくつかあります。
では、Engine クラスのコードをチェックするための単体テストをどのように追加できますか? おそらく
、動作を公開する Car クラスまたは Engine クラスにいくつかのメソッドがあり、
単体テストを記述できるようになるでしょう。次に問題は、Engine クラスの動作を公開する必要がある場合
、Engine クラス
が独立した方がよいのではないかということです。

あるいは、Engine クラスのメソッドを明示的にテストする必要がない場合があり
、Car のメソッドの単体テストは Engine クラスのコードもカバーし
ます。次に、Engine クラスと Car クラスの緊密な統合を反映して
おり、内部クラスとして残ることができることを意味します。

于 2009-12-16T08:26:10.510 に答える