最近の就職の面接で、私はSOLIDについての質問に答えることができませんでした-さまざまな原則の基本的な意味を提供する以外に。本当にバグです。数日かけて掘り下げましたが、まだ十分な要約を出していません。
インタビューの質問は:
SOLIDの原則に厳密に従っていると言った.Netプロジェクトを見るとしたら、プロジェクトとコード構造の観点から何を期待しますか?
私は少しもがいて、質問に本当に答えなかったので、爆撃されました。
この質問をどのようにうまく処理できますか?
最近の就職の面接で、私はSOLIDについての質問に答えることができませんでした-さまざまな原則の基本的な意味を提供する以外に。本当にバグです。数日かけて掘り下げましたが、まだ十分な要約を出していません。
インタビューの質問は:
SOLIDの原則に厳密に従っていると言った.Netプロジェクトを見るとしたら、プロジェクトとコード構造の観点から何を期待しますか?
私は少しもがいて、質問に本当に答えなかったので、爆撃されました。
この質問をどのようにうまく処理できますか?
回答:
S =単一責任の原則
したがって、フォルダ/ファイル構造とオブジェクト階層が適切に整理されていることを期待しています。各クラス/機能には、その機能が非常に明白であるという名前を付ける必要があり、そのタスクを実行するロジックのみを含める必要があります。
数千行のコードを持つ巨大なマネージャークラスを見た場合、それは単一の責任が守られていないことを示しています。
O =オープン/クローズドプリンシプル
これは基本的に、既存の機能に最小限の影響を与える/変更を必要とする新しいクラスを介して新しい機能を追加するという考え方です。
オブジェクトの継承、サブタイピング、インターフェース、抽象クラスを使用して、機能のデザインを実際の実装から分離し、他の人が影響を受けずに他のバージョンを一緒に実装できるようにすることを期待しています元の。
L =リスコフ置換原理
これは、サブタイプを親タイプとして扱う機能に関係しています。適切な継承オブジェクト階層を実装している場合、これはC#ですぐに使用できます。
サブタイプ自体をインスタンス化して処理するのではなく、共通オブジェクトをベースタイプとして扱い、ベース/抽象クラスのメソッドを呼び出すコードを期待しています。
I =インターフェイス分離の原則
これはSRPに似ています。基本的に、あなたは(インタフェースとしての機能の小さなサブセットを定義し、デカップリングあなたのシステムを維持するために、これらと連携例えばFileManager
I / Oファイルを扱うの単一responsibiltyがあるかもしれませんが、それは実現可能性がありIFileReader
とIFileWriter
読書のための具体的な方法の定義を含んでいましたファイルの書き込み)。
D =依存性反転の原理。
繰り返しますが、これはシステムを分離した状態に保つことに関連しています。おそらく、Unity
またはなどのソリューションで使用されている.NET Dependency Injectionライブラリ、Ninject
またはのようなServiceLocatorシステムの使用に目を光らせているでしょうAutoFacServiceLocator
。
依存性注入を伴う小さなクラスとインターフェースがたくさんあります。おそらく大きなプロジェクトでは、IoCフレームワークを使用して、これらすべての小さなオブジェクトのライフタイムを構築および管理することもできます。https://stackoverflow.com/questions/21288/which-net-dependency-injection-frameworks-are-worth-looking-intoを参照してください
堅固な原則に厳密に従う大きな.NETプロジェクトは、すべての人が使用できる優れたコードベースを必ずしも意味しないことに注意してください。インタビュアーが誰であるかに応じて、彼/彼女は、SOLIDの意味を理解していること、および/または設計原則に従って独断的にチェックしていることを示すことを望んでいたかもしれません。
確かに、従う必要があります:
Sイングル責任の原則、あなたがそれらのそれぞれが、一つのことをやって多くの小さなクラスを持つことになりますので、のみ
Oペンクローズの原則。これは通常.NETで依存性注入を使用して実装されます。これには、以下のIとDも必要です。
L iskovの置換原理は、おそらくc#で1ライナーで説明することは不可能です。幸いなことに、これに対処する他の質問があります。たとえば、https://stackoverflow.com/questions/4428725/can-you-explain-liskov-substitution-principle-with-a-good-c-sharp-example
私は棲み分け原理は、オープン・クローズの原則と連携して動作しますnterface。文字通り従えば、少数の「大きな」インターフェースではなく、非常に多くの非常に小さなインターフェースを好むことを意味します。
Dの高レベルのクラスは、低レベルのクラスに依存してはならないependency反転原理は、両方のは、抽象化に依存しなければなりません。
日常業務でSOLIDを支持しているショップのコードベースで私が期待する基本的なこと:
多数のアダプターおよび複合パターン-多くのアダプターパターン(別のインターフェイスの機能に「パススルー」することで1つのインターフェイスを実装するクラス)を使用して、1つの目的のために開発された依存関係のプラグインをわずかに合理化することを期待しますその機能も必要とされるさまざまな場所。コンソールロガーをファイルロガーに置き換えるだけの簡単な更新は、使用するファイル名を指定する手段を公開するためにインターフェイスが更新された場合、LSP / ISP / DIPに違反します。代わりに、ファイルロガークラスは追加のメンバーを公開し、アダプターは新しいものを非表示にすることでファイルロガーをコンソールロガーのように見せます。そのため、これらすべてをスナップするオブジェクトのみが違いを知る必要があります。
同様に、オブジェクト(OCP)の変更を避けるために、クラスが既存のものと同様のインターフェースの依存関係を追加する必要がある場合、通常の答えは、Composite / Strategyパターン(依存関係インターフェースを実装し、複数のそのインターフェイスの実装。クラスがさまざまな量のロジックを使用して、1つ、いくつか、またはすべての実装に呼び出しを渡すことができます。
SOLIDの「O」が「役に立たず、あまり理解されていない」というJon Skeetの議論に注意をそらし、Alistair Cockburnの「保護されたバリエーション」とJosh Blochの「継承のための設計、または禁止」について話させます。
Skeetの記事の短い要約(元のブログ投稿を読まずに彼の名前を落とすことはお勧めしませんが!):
OPは、「どうすればこの質問に対処できたでしょうか?」と尋ねました。面接を行うシニアエンジニアとして、さまざまなコードデザインスタイルの長所と短所について知的に話すことができる候補者に、箇条書きのリストからガタガタすることができる人よりも、非常に興味があります。
別の良い答えは、「まあ、それは彼らがそれをどれだけよく理解しているかに依存する。もし彼らが知っているのがSOLID流行語だけなら、継承の濫用、依存性注入フレームワークの乱用、どれもどれも100万個の小さなインターフェースはないだろう」製品管理との通信に使用されるドメイン語彙を反映します。...」
さまざまな時間でこれに答えることができる方法はおそらくいくつかあります。ただし、これは「SOLIDの意味を知っていますか?」の行に沿っていると思います。そのため、この質問に答えることは、要点を突き止めて、プロジェクトの観点から説明することになるでしょう。
したがって、次のように表示されます。
これは素晴らしい質問ですが、難しいインタビューの質問だと思います。
SOLIDの原則は、クラスとインターフェイス、およびそれらの相互関係を実際に管理します。
この質問は、実際にはファイルに関係するものであり、必ずしもクラスに関係するものではありません。
簡単な観察または答えは、一般にインターフェイスだけを保持するファイルが表示されることです。多くの場合、慣例では大文字のIで始まります。さらに、ファイルのコードが重複していないこと(特にモジュール、アプリケーション、またはライブラリ内)、およびモジュール、アプリケーション、またはライブラリ間の特定の境界を越えてコードが慎重に共有されることに言及します。
Robert Martinは、Boochメソッドを使用したオブジェクト指向C ++アプリケーションの設計(Cohesion、Closure、Reusabilityのセクションを参照)およびClean Codeで、C ++の領域でこのトピックについて説明しています。