「モジュール性」を達成するために部分クラスを使用することは一般的ですか?


24

私は最近、別のチームが部分的なクラスとして135個のファイルに分割された約800個のメソッドを含む「ゴッドクラス」を作成するというコードベースの状況に遭遇しました。

私はこれについて他のチームに尋ねました。私の腸の反応は軌道からそれを消すことでしたが、彼らはそれが良い設計であり、一般的な慣行であり、新しい開発者は残りの知識がほとんどなくても機能をボルトで固定できるため、「モジュール性」と「実装の容易さ」を促進すると主張しますシステムの。

これは実際に一般的な慣行ですか、それとも何らかの方法で良いアイデアですか?私はこの獣を倒す(または少なくともそれがさらに成長するのを防ぐ)ためにすぐに対策を講じたいと思っていますが、私は自分が間違っていると信じています。


6
火で殺します!しかし、真剣に、他のチームはこの申し立てられた一般的な慣行の引用を提供できますか?
-MattDavey

1
なし。私は彼らが煙を吹いていると確信していますが、ハンマーを落とす前にデューデリジェンスをしようとしています。
ジョシュアスミス

いつもこれをしなかった理由は何ですか?
ジェフ

3
135のファイルにまたがる800のメソッドがすべて共通しているものを1つの文で説明するように依頼します。健全で合理的​​なクラスであれば、それに答えることができるはずです。
Carson63000

3
@ Carson63000「プロジェクトに必要なすべての機能を実行します。」あなたの1つの文があります。
リャサル

回答:


39

これは決して良い考えではありません。

フォームデザイナを支援するために、部分クラスが存在します。他の理由で(そして、おそらく意図した目的のために、しかしそれは別の問題です)それらを使用するのは悪い考えです。

このように見てください:1つのファイルに800個のメソッドを持つ神クラスがあり、すべてがどこにあるかを知っている場合、それは悪いことです。 135個のファイルに散らばっており、どこがすべて良いのかわからない場合


1
私はほとんど同意しますが、partial生成されたコードがなくても役立つことがまれなケースがあると思います。ネストされたクラスのようなものがある場合はどうでしょうか?
svick

1
@svick:部分クラスは興味深いですが、通常は必要ありません。ネストされたクラスがある場合に、クラスを個別のファイルに分割することが役立つ理由はわかりません。独自の物理ファイルにネストされたクラスが必要な場合を除きます。その場合は... まあまあ大丈夫です。;)
FrustratedWithFormsDesigner

5
明示的なインターフェイスの実装には、特にSystem.IConvertibleのような部分クラスを使用することがあります。どういうわけか、私のクラスに巨大な#regionを置くよりもきれいに見えます。
MattDavey

1
ネストされたクラスのコメントは実際には本当に良いアイデアであり、私もそれを考えたことがありません。しかし...それは「モジュール性」よりも組織に関係しています
シェルドン・ウォーケンティン

1
「フォームデザイナを支援するために、部分クラスが存在します。」一般的には正しいですが、「...およびその他のコードジェネレーター」を追加します。私はあなたの答えの残りに同意します;)
サイラス

14

質問は:

これは実際に一般的な慣行ですか、それとも何らかの方法で良いアイデアですか?

現在利用可能な答えの中には、圧倒的なノーがあります。ですから、それについて私が口にすることができるものは他にほとんどありません。手続き型のコードでさえモジュール化することができ、キッチンシンク以外のすべて含めて、モジュール性を実現する方法ではありません。1つの巨大なクラスがパーシャルに分割されると、それがすべて1つの大きな混乱になります。

しかし、その質問は、見逃された本当の重要な部分への赤いニシンです。OPには次のような状況についての説明もあります。

(...)私の腸の反応は軌道からそれを消すことでしたが、彼らは主張します...

(...)私はこの獣を倒す(または少なくともそれがさらに成長するのを防ぐ)ために即座の措置を講じる傾向がありますが、私は間違っていると信じています。

あなたの馬を保持します!

これは、比fig的に話すモノクルを比fig的なお茶に落とすものです。

私は似たような状況にあって、私はあなたを教えてください聞かせてきました:しないでください、そうする衝動のために落ちます。もちろん、Nuke Hammer of Justiceをチームに落とすこともできますが、そうする前に、次の難問でユーモアを交えてください。

チームにコードがダメで落ち着くことを伝えるとどうなりますか?

(...またはそのようなものですが攻撃的ではありません、あなたが彼らに全力を尽くすことにした場合、彼らが何をしようとも気分を害するので、それは本当に重要ではありません)

コードベースの現在の状況は何ですか?それは働いていますか?それから、彼らのコードが本質的にひどいことを彼らのクライアントに説明する大きな問題を持つでしょう。どんな理由があっても、それが機能している限り、ほとんどのクライアントはコードがどのように編成されているかを気にしません。

また、自分の靴に身を置く、彼らは何をしますか?次の非常に可能な結果であなたを楽しませてください:

チームメンバー1:「この数年間、私たちは間違ったことをしてきたと言っている人がいます。」

チームメンバー#2および#3:「なんてこったい。」

影響力のあるチームメンバー#4:「心配する必要はありません。経営陣に行って、それを嫌がらせとして報告します。」

影響力のあるチームメンバー#4がそこで何をしたかをご覧ください。彼は経営陣に行き、会社のカルマを減らしました。彼はアメリカ・イタリア人かもしれません、みんなにそれについて心配しないように言っていますが、それから私はそれについて人種差別主義者になるでしょう。

問題のあるチームをコーナーにペイントして、彼らが長い間間違ったことをしたことを認めさせることも悪い考えであり、同じことをもたらします。あなたは尊敬といくつかのオフィス政治カルマを失います。

「チームにレッスンを教える」ために何人かの人々にサインオフしてもらったとしても、明らかに何かを成し遂げたかなり賢い人々にこれをしていることを思い出してください。コードが書き直されたり、リファクタリングされたり、変更されたり、何であれ、問題が発生すると、ファイヤースターターとしての責任を負うことになります

このような状況に敵対することは、非難ゲームの悪循環になる危険性があるため、ほとんどが負けゲームです。これは、この状況では次善の結果です。あなたが勝ったとしても、あなたは突然他の誰かがやった混乱を引き渡されます。

他の(かなり成熟した)方法があります

私はかつて同様の状況にありましたが、その後膝に矢を取りました。だから、しばらくして、突然のキャリア変更の矢が頭に浮かんだので、Terrence RyanのDriving Technical Change」という本を受け取りました。それは懐疑論者のいくつかのパターンをリストします、人々の種類は良い考えに基づいて行動しません。これらはすべて、OPの場合に適用される可能性が最も高いです。

  • 無知-彼らは本当に他の方法があることを知らなかったか、単に理解しませんでした。通常、ジュニア開発者はこのカテゴリに適合しますが、必ずしもそうとは限りません。(正直に言うと、これよりも明るいジュニア開発者に会ったことがあります。)
  • 群れ-部分クラスを使用するよりも優れたテクニックを知っていましたが、許可されていることを知りませんでした。
  • The Cynic-彼らは、単に議論するために、部分的なクラスを持つことはあなたのアイデアよりも優れていると主張するのが好きです。群衆の前に立つのではなく、群衆の中でそれを行うのは簡単です。
  • The Burned-何らかの奇妙な理由で、彼らは新しいクラスを作成することを好みません。おそらく、彼らはそれを難し​​すぎると感じています。
  • The Time Crunched-彼らは忙しいので、コードを修正する手間がかかりません。
  • The Boss-彼らは、「それでうまくいく。だからなぜわざわざ?」と思う。
  • 不合理-わかりました、彼らは完全に狂っています。

この本は戦略のリストなどを続けていますが、OPの場合は説得の問題です。アンチパターンに関する事実に強く立ち向かうだけでは不十分です。

コードの品質を向上させることに関心がある場合は、少なくとも問題のあるチームに自分の混乱を繰り返して修正する機会を与えてください。個人的には、主要な質問を聞いて尋ねることで彼らを揺さぶろうとします。

  • 彼らの神のクラスは正確に何をしていますか?
  • 問題が発生しましたか?バグはありますか?彼らにそうするように告げることなく、健全な修正を提案します。
  • この神クラスをAPIとして使用している場合:コード全体を使用するよりもコードを使用する簡単な方法はありますか?より簡単な例を提案し、それらがどのように反応するかを見てください。
  • 関数を記述する必要なく、いくつかの機能を別の機能に切り替えることはできますか?
  • 彼らはいくつかのトレーニングを必要としていますか?経営者にそれをやらせるように説得したり、パターンや慣行について昼食会を開いたりできますか?

... 等々。彼らが前進できるように、彼らに小さな提案をしてください。それは時間がかかり、いくつかのオフィス政治グレードの肘のグリースが必要になりますが、忍耐と勤勉は美徳ですよね?


これは非常に洞察に満ちた答えです。あなたが新しい開発者であれば、これを理解する必要があります。ほとんどの経験豊富な開発者は、数年後にこれを実現し、一部の開発者は決して実現しません。
FishySwede

6

MSDNの部分クラスとメソッドのページでは、部分クラスを使用する2つの状況が提案されてい
ます。1.巨大なクラスを複数の個別のファイルに分割する。
2.自動生成されたソースコードを配置する場所を確保する。

2は、Visual Studioで頻繁に使用されます(aspxファイルやwinformなど)。これは部分クラスの合理的な使用です。

1はあなたのチームがやっていることです。部分クラスを使用することは、巨大なクラスがある場合にモジュール性を実現するための完全に合理的な方法ですが、巨大なクラスを持つこと自体は不合理です。言い換えれば、巨大なクラスを持つことは悪い考えですが、巨大なクラスを持つつもりなら、部分的なクラスは良い考えです。

異なるユーザーが作業できるようにクラスを個別のファイルにインテリジェントに分割できる場合、代わりに個別のクラスに分割することはできませんか?


+1を「代わりに別のクラスに分割することはできませんか?」これはまさに私たちが提案していることです。もともとそのようにしていたはずだという常識のようです。
ジョシュアスミス

4

そのため、最終的には、OOPなしで通常の手続き開発を行っています。それらには、すべてのメソッド、変数、その他が含まれる1つのグローバル名前空間があります。

彼らが間違ったことをしていることを説得するか、そこから地獄に出る。


1

ユーティリティクラスには、他のメソッドと賢明に組み合わせてクラスを作成できないメソッドが含まれています。135のファイルに分割された800以上のメソッドがある場合、誰かがいくつかの一般的なメソッドを見つけることができたようです...

1つのユーティリティクラスがあるからといって、別のユーティリティクラスを使用できないという意味ではありません。

ほとんど無関係のメソッドが800個あるとしても、その解決策は1つの大きなクラスではなく、多くのファイルです。解決策は、名前空間、いくつかのサブ名前空間、および多くの小さなクラスです。これはもう少し手間がかかります(クラスとメソッドの名前を考え出す必要があります)。しかし、この混乱をクリーンアップするときが来ると、あなたの人生が楽になり、その間、インテリセンスが使いやすくなります(つまり、メソッドを使用する場所を見つけやすくなります)。

いいえ、これは一般的ではありません(無料の関数の数よりもファイルの数が多い)。


0

私はこれがまったく好きではありません。ただし、開発者が開発中に部分クラスを理解することは、特に多数のメソッドを同時に開発できるため、特にそれらの間にあまり依存関係がない場合に意味があります。

別の可能性は、これらの部分クラスが、自動生成されたコアクラスを修正するために構築されたことです。この場合、それらに触れないでください。さもないと、再生成時にカスタムコードがホイップアウトされます。

誰も勉強せずにこれを簡単に維持できるかどうかはわかりません。これを強制終了しても、メソッドの数は減りません。私にとって、メソッドの数と複雑さは本当の問題です。メソッドが本当にクラスに属している場合、1つの巨大なファイルを用意しても、特にメンテナンスが楽になりません。実際、ワイルドカード検索などのばかげたミスに対してすべてのコードを公開する方がエラーが発生しやすくなります。交換します。

したがって、注意して殺害の決定を正当化してください。また、必要なテストを検討してください。


0

135ファイルが実際に従来のクラスが行うことと同様にメソッドをグループ化すると仮定すると、実用的な設計の観点からはまったく問題ありません。1ファイルあたり平均6メソッドです。プロジェクトを設計するための最も一般的または伝統的な方法ではありません。それを変更しようとすると、多くの問題が発生するだけで、病気にはなりません。プロジェクトをオブジェクト指向標準に準拠させると、解決できる限り多くの問題が発生します。複数のファイルが実際に意味のある分離を提供しない場合は、まったく別の問題です。


3
手続き型コードをオブジェクト指向にリファクタリングすることは、一般にその問題を抱えています。これを修正することは大きな作業であり、チームに適切にさらに適切にコーディングするよう指導することです。 )彼がリファクタリングするように説得した場合。これが、このようなリファクタリングを行うために誰も一生懸命にプッシュしない理由です(少なくとも、一度結果を確認したら)。また、それが素晴らしいデザインだと思う場合は(まあ)、5年後にこの答えを再訪し、あなたの考えを教えてください(5年ごとにデザインについて知っていることをすべて再学習しているようです)。
ビルK

@BillKあなたが10年待つなら、おそらくあなたが知っていることはおそらく現在の「イン」設計哲学になるでしょう。
リャサル

135個のファイルは一般に関連するメソッドをグループ化しますが、それは(私にとっては)まだ良い考えではありません。このシステムをテスト中にしたいのですが、800メソッドのヒドラをスタブ/モックすることはロバにとってpainい痛みになるでしょう。
ジョシュアスミス

@Ryathalは「中に入っている」ものではなく、(良い理由で)良いデザインだと思うものであり、練習して改善するにつれて、考えているほど良いアイデアではないことに気づきます。それは5年ごとに起こるようであり、実際に私たち全員がプラクティスを永久に改善する過程にいる優秀なデザイナーであることに気付いたので、それが一部の人々のコメントに対する私の反応を抑えていることを認識すると。私が心配する唯一のプログラマは、5年前に書いたコードを改善できるとは思わなかったプログラマです。
ビルK

0

既に指摘した答えに加えて、部分クラスは、クラス階層を個別のレイヤー固有のファイルにクロスカットする機能を整理するレイヤー化設計で役立ちます。これにより、ソリューションエクスプローラーを使用して、レイヤーごとの機能を(ファイル編成ごとに)ナビゲートし、クラスビューを使用してクラスごとの機能をナビゲートできます。ミックスインやトレイトをサポートする言語を使用したいと思いますが、部分クラスは控えめに使用した場合の合理的な代替手段であり、適切なクラス階層設計の代わりにはなりません。

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