2

自分のプログラミング スキルと習慣を 21 世紀に持ち込もうとする自主的な取り組み (Pascal と Fortran から C# と C++ への移行) で、入手可能なソース コードをかなりの量研究してきました。私が判断できる限り、クラスは一意の「スタンドアロン」エンティティです (関数の先祖によく似ています)。

ただし、1 つ以上のクラスが別のクラス内にネストされている多くのインスタンスに出くわしました。この点に関する私の「本能」は、そうするのは単に非常に貧弱な方法論によるものであるということですが、私はまだそのような決定を真に行うための最新の OOP 方法論に十分慣れていません。

したがって、次の重複する質問:

あるクラスを別のクラスにネストする正当な理由はありますか? もしそうなら、各クラスが完全に独立しているのとは対照的に、そうすることの理論的根拠は何ですか?

(注: 私が見た例では C# を使用していますが、この側面は C++ にも同様に当てはまるようです。)

4

4 に答える 4

3

うーん、これは非常に示唆に富む答えを必要とするかもしれないので、多くの人が私の答えに反対するでしょう. 私は、ネストされたクラスは本当に必要ないと信じている人の 1 人であり、あなたの声明に同意する傾向があります。

この点に関する私の「本能」は、そうするのは単に非常に貧弱な方法論によるものであるということです

ネストされたクラスを設計する必要性を人々が感じるケースは、機能が外部クラスで設計された動作に密接に結合されている場合です。たとえば、イベント処理は内部クラスで設計できます。または、Threading動作が内部クラスへの道を見つけることができます。

どちらも明確な責任を持つ 2 つの小さなクラスになるように、「外部」クラスから特定の動作をリファクタリングします。

私にとって、内部クラスを設計することの主な欠点は、 TDD (テスト駆動開発)としてプリンシパルを使用するのが (より) 難しい機能を乱雑にする傾向があることです。

テスト駆動のプリンシパルに依存していなければ、大きな害はないと思います。それは(多くのことと同様に)好みの問題であり、正しいか間違っているかの問題ではありません. 私は、その話題が長くて疲れる議論につながる可能性があることを学びました. static「ヘルパーになる」以上のことをする傾向があり、時間の経過とともにますます多くの状態を取得するヘルパー クラスを使用する必要があるかどうかに非常に似ています。

実際の例に出くわすと、議論はより具体的になる可能性があります。それまでは、ほとんど人の「勘」になります。

于 2013-03-03T20:15:23.043 に答える
1

C# での入れ子になったクラスの一般的な用途には、モジュールの内部名前空間で公開したくない、クラスによる内部使用のためのクラスが含まれます。たとえば、外部に公開しない例外をスローする必要がある場合があります。その場合、ネストされたクラスにして、他の人が使用できないようにする必要があります。

もう 1 つの例は、バイナリ ツリーのNodeクラスです。クラス外に公開したくないものになるだけでなく、内部操作のためにプライベート メンバーへのアクセスが必要になる場合があります。

于 2013-03-03T20:55:07.513 に答える
0

ネストされたクラスを持つことには賛否両論があります。プロは、イリジウムが言及したような意図的な使用や、WPF/MVVMのコマンドパターンIEnumerator<T>を容易にするためのネストクラスを中心にしています。SQLの作成、読み取り、更新、削除(CRUD)操作は、基幹業務/データ駆動型アプリのこれらのパターンを使用して、コード内のクラス/コマンドにカプセル化するのによく使用されます。

ネストクラスに関連付けられているネガティブは、デバッグに関連付けられています。ネストするクラスが多いほど、複雑さが増し、バグの発生が容易になり、すべてをデバッグするのが難しくなります。コマンドパターンのようなものをそのまま使用すると、クラスやコマンドが多すぎてクラスが肥大化する可能性があります。

于 2013-03-03T21:47:07.813 に答える
0

ネストされたクラスに非常に頻繁に遭遇する領域の 1 つに (おそらく気付かないかもしれませんが) 列挙子 (つまり、 を実装するクラスIEnumerator<T>) があります。

コレクションが複数の同時列挙をサポートするには (たとえば、複数のスレッドで、またはforeach同じコレクションのネストされたループでさえも)、列挙ロジックをコレクションから別のクラスに分離する必要があります。

ただし、列挙子が正しく機能するためには、コレクションの実装の詳細に関する特定の知識が必要になることがよくあります。完全に別の (ネストされていない) クラスでこれを行う場合、それらの内部を実際よりもアクセスしやすくする必要があり、カプセル化が壊れます。(メンバーを使用して実行できると主張する人もいるかもしれませんがinternal、実装の詳細を同じアセンブリのメンバーに「公開するだけ」であっても、これはカプセル化をある程度破ると思います)。

列挙子にプライベートのネストされたクラスを使用することにより、ネストされたクラスがそれを含むクラスの内部にアクセスできるため、適切なカプセル化を維持しながらこれらの問題が解消されます。

于 2013-03-03T20:45:54.377 に答える