web-dev-qa-db-ja.com

共通フィールドを基本クラスに移動するのはいつですか?

現在、2つの派生クラスABがあり、どちらにも共通のフィールドがあり、基本クラスに移動する必要があるかどうかを判断しようとしています。

これは基本クラスから参照されることはなく、将来のある時点で別のクラスCが派生し、_field1がない場合、 "のプリンシパルにはならないでしょう。最小限の特権」(または何か)に違反した場合

public abstract class Base
{
    // Should _field1 be brought up to Base?
    //protected int Field1 { get; set; }
}

public class A : Base
{
    private int _field1;
}

public class B : Base
{
    private int _field1;
}

public class C : Base
{
    // Doesn't have/reference _field1
}
16
samis

それはすべて、解決しようとしている正確な問題に依存します。

具体例を考えてみましょう。抽象基本クラスはVehicleであり、現在、具体的な実装BicycleCarがあります。 numberOfWheelsBicycleおよびCarから車両に移動することを検討しています。これを行う必要がありますか?番号!すべての車両に車輪があるわけではないからです。 Boatクラスを追加しようとすると、壊れてしまうことはすでにわかります。

ここで、抽象基本クラスがWheeledVehicleである場合、numberOfWheelsメンバー変数をそこに含めることは論理的です。

あなたが見ることができるように、それは単純なイエスかノーの答えではないので、あなたはあなたの問題に同じロジックを適用する必要があります。

34
Pete

論理的に言えば、フィールドをサブクラスに複製するか、基本クラスに共通するフィールドを配置する以外に、3つのオプションがあります。これは、2つの間で共通のプロパティを持つ階層に新しいサブクラスを導入することです。 @Peteは、そこに完全に行くことなくこれを示唆しています。

@Peteの例を使用して、元の基本クラスから派生するWheeled Vehicleの(おそらく抽象)サブクラスを導入します— 2つのサブクラスはそれから派生します。したがって、元の基本クラスは車輪で汚染されていませんが、車輪の共通性はDRY(車輪を持つサブクラス間では繰り返されません)です。

もちろん、これはあなたの目的にとってやり過ぎかもしれませんが、それはクラス階層メカニズムによってサポートされています。

13
Erik Eidt

ここで悪魔の擁護者を演じます。

現時点ではnothingを実行する必要があります。

乾いた?いいえ。しかし、後で簡単に元に戻すことができない時期尚早な抽象化よりも、少しだけ複製する方がよいでしょう。プロパティを共通の基本クラスに移動するリファクタリングは簡単です。逆に行くのはそうではありません。成り行きを見守る。

この種の決定を行うとき、私は「3のルール」を使用する傾向があります。 3つの異なる場所で、それから初めて、チェーンを上に移動することを検討します。 N.B.あなたは2歳です。

9
Jared Smith

一般的には、ベースクラスに移動します。ここにはトレードオフがあるため、目的の「はい/いいえ」はないと思います。未使用のフィールドを運ぶことと、複雑さを減らすことです。

私は通常、共有される可能性のあるものをすべて含む「重い」基本クラスを好みます。すべての派生クラスで子孫のシリアル化メソッドを必要としないため、これによりファイルへのシリアル化が簡単になります。しかし、そのような問題がない場合、またはメモリ使用量を減らすためにできる限りのことを行う必要がある場合は、必要な場所にフィールドを保持するだけで十分です。

一般的なフィールドを紹介する「中間」クラスは、フィールドの数が非常に限られている場合は問題ありません。ただし、さまざまな組み合わせで数十のフィールドを使用している場合、アプローチによって複雑さが劇的に高まり、それぞれが特定のフィールドセットを導入する多くの中間クラスにつながることに注意してください。これは、メンテナンスの問題になる可能性があります。

2
GrandmasterB