ネストされたクラスは過小評価されていますか?


9

私は他の誰もが知らないことを知っていると言っているわけではありませんが、ネストされたクラスを使用してますます多くのデザインを解決してきました。設計メカニズム。

これは私に質問を導きます:彼らが私を噛むように戻ってきたときに私が発見する理由のために、私は本質的に悪い道を進んでいますか、またはネストされたクラスはおそらく過小評価されているものですか?

次に、私がそれらを使用した2つの例を示します。https://gist.github.com/3975581-1つ目は、密接に関連する階層的なものを一緒に保つのに役立ち、2つ目は、保護されたメンバーへのアクセス権をワーカーに与えました...


私は回答/洞察に感謝を伝えたいだけです-回答を選ぶ方法がわからないので、私が得たアドバイスを
熟考して

回答:


6

私はこれを「めったに使用されない設計メカニズム」とは呼びません。少なくとも、普遍的ではありません。一部の寄稿者がネストされたクラスの使用を嫌うショップもありますが、これは完全な機能ではありません。

アセンブリの可視性を備えたクラスの存在とラムダの導入により、ネストされたクラス*の必要性が大幅に減少しましたが、それらは依然として有効な設計上の選択です。名前空間内の内部クラスと一部重複がありますが、ネストされたクラス機能は、クラスを完全に別のクラス内に隠すことができるという点で独特です。


* C#で利用可能な他の代替手段がJavaにはないため、Javaでの同様の機能の使用ははるかに高くなります。


それでは、OOPデザインの本質に従って、クラスを完全に別のクラスに隠すのは良いことでしょうか?
Maxood 2016

1
@Maxoodクラスを非表示にできる場合は、非表示にするとよいでしょう。APIのユーザーは、APIの実装方法についてできる限り知っておく必要があります。
dasblinkenlight 2016

3

少しの間、別のクラス内にクラスを作成していることを考えてください。クラスはプログラムの他の場所では使用されません。他の場所で使用している場合は、他のクラスと同じように、通常のパブリッククラスにするからです。

したがって、OOPを優れたものにする(再利用可能な)はずのものがここにはありません。さらに、親クラス内の通常のメソッドやプライベートメンバーでは達成できなかった、ネストされたクラスで達成できることは何ですか?

ネストされたクラスを利用する便利なソフトウェアパターンについては、こちらをご覧ください


10
私は再利用性のものを買ったことがありません、少なくともそれが通常置かれる方法では。(1)既存のコード/クラス(あなたが話しているように見え、私が通常再利用の定義として見るもの)を呼び出すことは、OOPとはまったく関係がなく、基本的なモジュール性にすぎません。(2)サブタイプポリモーフィズムは、OOPの定義特性の1つであり、具体的なクラスにアクセスできるかどうかにかかわらず、特定の実装を無関係にすることでクライアントコードを再利用できます。IOWは私が購入した再利用ですが、ネストされたクラスでも同様に機能します。

1
親クラスによって指定された名前空間の絶縁もあると思います。したがって、必要に応じて、クラスAとBの両方にネストされたクラス「Params」を含め、包含クラスの非パブリックメンバーにアクセスできます。それらは両方とも、クラスの外部で使用される内部クラスを持つ理由ではありませんか?
アーロンアノダイド

@AaronAnodideネストされたクラスを使用する良い方法についての答えになるはずです。それはまさに私がそれらを使用する方法/理由であり、コードを整理するのに役立ちます。
12

2

am I going down an inherintly bad path

2番目の例(workerサブクラス)では間違いなくそうです。各サブクラスをスーパークラスの特定の状態にマップしました。したがって、スーパークラスに状態を追加するたびに、3つの場所で状態を変更する必要があります(スーパークラスに状態を追加し、新しいサブクラスを追加し、派生クラスのコンストラクターを変更してサブクラスをリストに追加します) )。

ネストされたクラスを使用してプライベートメンバーにアクセスすることは有効であるように見えますが(私が個人的に行ったことはありません)、ここでは特定のケースが機能しません。

ボディパーツ例も。ネストされたクラスはすべてパブリックであるため、名前空間を除いて実際には多くのことを行っていません。これらのクラスが成長してより多くの機能が含まれるようになった場合、ネストされたクラスがインターフェイスを乱雑にして、特定の何かを見つけるためにコードをふるいにかけることがわかります。また、ネストされたクラスがあるため、命名規則に違反し、クラスに小文字で名前を付ける必要があることにも気づきました(おそらくこれが選択でした)。しかし、これらの議論は実際に間違っていることよりも表面的なものです。

もちろん、具体化されていないアームを実装する必要がある場合を除きます。次に、ボディ/胴体/側面がないため、次のように腕を作成すると混乱を招きます。(紛らわしいケースにも注意してください)。

arm newArm = new Body.torso.side.arm("");

1

ネストされたクラスについて考えることができる唯一の利点は、それらをプライベート(または保護)できることです。この場合、クラスが外部クラスとそのクラスだけで使用されることを意図している場合、ネストされたクラスは機能をカプセル化するのに役立ちます。


1

私の経験では、ネストされたクラス

  • 私を悩ませるために戻ってきました
  • 隅を切りたかったときに使用されています
  • 悪夢をテストしました
  • 懸念の分離と全体的な設計に悪影響を及ぼした

あなたのクラスを簡単に見て、すぐに私はそう思います:

  • 授業が多いので見るのが辛い
  • 体全体を作成することなしに「指」をテストすることはできません
  • 胴体の複数の実装はできません。「人体」のコンテキストではそれほど明白ではないように見えますが、別のシナリオでは、これが明らかになります。

クラスを複数のクラスに分け、それらに別々の名前空間を与えてはどうでしょう。例えば

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.