タグ付けされた質問 「solid」

一連の設計原則のニーモニック:単一責任、オープンクローズ、リスコフ置換、インターフェース分離、依存関係逆転

16
単一責任原則を使用する場合、「責任」とは何ですか?
「単一責任の原則」が「1つのことだけを行う」ことを意味するものではないことは明らかです。それがメソッドの目的です。 public Interface CustomerCRUD { public void Create(Customer customer); public Customer Read(int CustomerID); public void Update(Customer customer); public void Delete(int CustomerID); } ボブ・マーティンは、「クラスには変更する理由が1つだけあるべきだ」と言っています。しかし、SOLIDを初めて使用するプログラマーの場合、これを考えるのは困難です。 私は別の質問への回答を書きました。そこでは、職責は役職のようなものであると提案し、レストランのメタファーを使って私の論点を説明することで主題について踊りました。しかし、それでも、クラスの責任を定義するために誰かが使用できる一連の原則は明確にされていません。 それでどうやってやるの?各クラスが持つべき責任をどのように決定し、SRPのコンテキストで責任をどのように定義しますか?

6
固い原則とコード構造
最近の就職の面接で、私はSOLIDについての質問に答えることができませんでした-さまざまな原則の基本的な意味を提供する以外に。本当にバグです。数日かけて掘り下げましたが、まだ十分な要約を出していません。 インタビューの質問は: SOLIDの原則に厳密に従っていると言った.Netプロジェクトを見るとしたら、プロジェクトとコード構造の観点から何を期待しますか? 私は少しもがいて、質問に本当に答えなかったので、爆撃されました。 この質問をどのようにうまく処理できますか?
150 c#  .net  solid 

10
これは、リスコフ代替原則の違反ですか?
TaskエンティティのリストとProjectTaskサブタイプがあるとします。タスクはいつでも閉じることができますが、タスクのProjectTasksステータスが[開始済み]になると閉じることができません。UIは、開始済みを閉じるオプションがProjectTask使用できないことを確認する必要がありますが、ドメインにはいくつかの保護手段があります。 public class Task { public Status Status { get; set; } public virtual void Close() { Status = Status.Closed; } } public class ProjectTask : Task { public override void Close() { if (Status == Status.Started) throw new Exception("Cannot close a started Project Task"); base.Close(); } } これClose()で、タスクを呼び出すときに、開始タスクのProjectTask状態の場合は呼び出しが失敗する可能性がありますが、ベースのタスクの場合は失敗しません。しかし、これはビジネス要件です。失敗するはずです。これは、リスコフ代替原理の違反とみなすことができますか?

12
SetWidthメソッドとSetHeightメソッドをオーバーライドすると、Rectangleから継承するSquareに問題があるのはなぜですか?
SquareがRectangleのタイプである場合、なぜSquareはRectangleを継承できないのですか?それとも、なぜそれが悪いデザインですか? 私は人々が言うのを聞いたことがあります: SquareをRectangleから派生させた場合、Squareは予想される任意の場所で使用できるはずです。 ここで問題は何ですか?そして、なぜSquareはあなたが長方形を期待するどこでも使えるのでしょうか?Squareオブジェクトを作成し、SquareのSetWidthメソッドとSetHeightメソッドをオーバーライドする場合にのみ使用できるのは、なぜ問題があるのでしょうか? Rectangle基本クラスにSetWidthメソッドとSetHeightメソッドがあり、Rectangle参照がSquareを指している場合、SetWidthとSetHeightは、一方を設定するともう一方がそれに合わせて変更されるため、意味がありません。この場合、SquareはRectangleによるLiskov Substitution Testに失敗し、RectangleからSquareを継承させるという抽象化は悪いものです。 誰かが上記の議論を説明できますか?繰り返しますが、SquareでSetWidthおよびSetHeightメソッドをオーバーライドすると、この問題は解決しませんか? 私も聞いた/読んだ: 実際の問題は、長方形をモデリングするのではなく、「再整形可能な長方形」、つまり作成後に幅または高さを変更できる長方形をモデリングすることです(それでも同じオブジェクトと見なします)。このように長方形クラスを見ると、正方形は「再成形可能な長方形」ではないことが明らかです。なぜなら、正方形は形を変えられず、依然として正方形であるためです(一般的に)。数学的には、数学的文脈では可変性は意味をなさないため、問題は見られません。 ここでは、「サイズ変更可能」が正しい用語だと思います。長方形は「サイズ変更可能」であり、正方形も同様です。上記の議論に何か欠けていますか?正方形は、任意の長方形と同様にサイズ変更できます。

4
次のSOLIDは、技術スタックの上にフレームワークを書くことにつながりますか?
私はソリッドが好きで、開発中にそれを使用して適用するように最善を尽くします。しかし、SOLIDアプローチがコードを「フレームワーク」コードに変えるように感じざるを得ません。つまり、他の開発者が使用するフレームワークまたはライブラリを作成する場合に設計するコードです。 私は通常、2つのプログラミングモードを練習しました-要件とKISS(通常のプログラミング)で要求される内容を多かれ少なかれ作成するか、他の開発者が必要とする柔軟性を提供する非常に一般的で再利用可能なロジック、サービスなどを作成します(フレームワークプログラミング) 。 もしユーザーが本当にアプリケーションにxとyのことをしたいだけなら、SOLIDに従って抽象化のエントリーポイントの全体を追加するのは理にかなっています。と?これらの抽象化のエントリポイントを追加する場合、ユーザーの要件を本当に満たしていますか、それとも既存のフレームワークと技術スタックの上にフレームワークを作成して将来の追加を容易にしますか?どちらの場合、顧客または開発者の利益に貢献していますか? これはJava Enterpriseの世界では一般的なことのように思われますが、ユーザーのUXに焦点を当てるのではなく、開発者にとってより良いUXになるようにJ2EEまたはSpringの上に独自のフレームワークを設計しているように感じますか?
70 frameworks  solid 

8
単一の責任原則を破ることなく、クラスに複数のメソッドを持たせる方法
単一責任の原則は、ウィキペディアで次のように定義されています 単一責任原則は、すべてのモジュール、クラス、または機能がソフトウェアによって提供される機能の単一部分に対して責任を負うべきであり、その責任がクラスによって完全にカプセル化されるべきであると述べるコンピュータープログラミングの原則です。 クラスの責任が1つだけの場合、どうすれば複数のメソッドを持つことができますか?各メソッドに異なる責任はありません。つまり、クラスには複数の責任があることになります。 単一の責任原則を実証する私が見たすべての例は、1つのメソッドのみを持つサンプルクラスを使用しています。例を見たり、1つの責任があると見なすことができる複数のメソッドを持つクラスの説明があると役立つ場合があります。

10
「final」キーワードが役立つのはなぜですか?
Javaには長い間派生できないクラスを宣言する力があったように思われますが、現在はC ++にもあります。しかし、SOLIDのOpen / Close原則に照らして、なぜそれが役立つのでしょうか?私には、finalキーワードのように聞こえますfriend-それは合法ですが、あなたがそれを使用している場合、ほとんどの場合、設計が間違っています。派生不可能なクラスが優れたアーキテクチャまたはデザインパターンの一部になるような例をいくつか提供してください。
54 java  c++  solid  final 

5
テスト可能なコードを促進する設計原則とは何ですか?(テスト可能なコードの設計とテストによる設計の推進)
私が取り組んでいるプロジェクトのほとんどは、開発と単体テストを分離して考えているため、後のインスタンスで単体テストを書くのは悪夢です。私の目的は、高レベルおよび低レベルの設計フェーズ自体の間にテストを念頭に置くことです。 テスト可能なコードを促進する明確に定義された設計原則があるかどうかを知りたい。私が最近理解するようになったそのような原則の1つは、依存性注入と制御の反転による依存性反転です。 SOLIDとして知られているものがあることを読みました。SOLIDの原則に従うと間接的に簡単にテストできるコードになるかどうかを理解したいですか?そうでない場合、テスト可能なコードを促進する明確に定義された設計原則はありますか? テスト駆動開発と呼ばれるものがあることを認識しています。ただし、テストを通じて設計を推進するよりも、設計段階でテストを念頭に置いてコードを設計することにもっと興味があります。これが理にかなっていることを願っています。 このトピックに関連するもう1つの質問は、既存の製品/プロジェクトをリファクタリングし、各モジュールのユニットテストケースを作成できるようにするためにコードとデザインを変更してもよいかどうかです。

5
IOCコンテナがOOP原則を破る
IOCコンテナの目的は何ですか?組み合わされた理由は、次のように簡略化できます。 OOP / SOLID開発の原則を使用する場合、依存関係の注入が面倒になります。下位レベルの複数のレベルの依存関係を管理し、構築を通じて依存関係を再帰的に渡す最上位のエントリポイントがあるか、必要に応じて依存関係を構築するファクトリー/ビルダーパターンおよびインターフェイスにコードが多少重複しています。 これを実行するには、何のOOP / SOLID方法はありませんと、超きれいなコードを持っているが。 前のステートメントが正しい場合、IOCコンテナーはどのようにそれを行いますか?私の知る限り、それらは手動のDIでは実行できない未知の手法を使用していないため、IOCコンテナは静的オブジェクトのプライベートアクセッサを使用してOOP / SOLID原則を破ることだけです。 IOCコンテナは、背後で次の原則を破っていますか?私はよく理解しているので、これは本当の質問ですが、他の誰かがより良い理解を持っていると感じています スコープ制御。スコープは、コード設計に関するほとんどすべての決定の理由です。ブロック、ローカル、モジュール、静的/グローバル。スコープは、ブロックレベルでできるだけ多く、静的でできるだけ少なくする必要があります。宣言、インスタンス化、およびライフサイクルの終了が表示されます。言語とGCは、明示的に明示している限り、スコープを管理することを信頼しています。私の研究では、IOCコンテナがほとんどまたはすべての依存関係を静的として設定し、バックグラウンドでAOP実装を介して制御していることがわかりました。したがって、何も透明ではありません。 カプセル化。カプセル化の目的は何ですか?なぜプライベートメンバーを保持する必要があるのですか?実際的な理由により、APIの実装者は、状態(所有者クラスによって管理される必要があります)を変更して実装を中断することはできません。しかし、セキュリティ上の理由から、メンバー状態を追い越し、検証とクラス制御をバイパスするインジェクションが発生しないようにします。したがって、プライベートメンバーへの外部アクセスを許可するためにコンパイル時間の前に何らかの形でコードを挿入するもの(モックフレームワークまたはIOCフレームワーク)は非常に巨大です。 単一責任の原則。表面的には、IOCコンテナは物事をよりきれいにするようです。しかし、ヘルパーフレームワークなしで同じことを達成する方法を想像してください。十数個の依存関係を持つコンストラクターが渡されます。それはIOCコンテナーでそれをカバーすることを意味するものではありません、それは良いことです!コードをリファクタリングし、SRPに従うことを示すサインです。 オープン/クローズ。SRPがクラスのみではないように(メソッドはもちろん、SRPを単一の責任ラインに適用します)。Open / Closedは、クラスのコードを変更しないという単なる高レベルの理論ではありません。プログラムの構成を理解し、何が変更され、何が拡張されるかを制御する習慣です。IOCコンテナは、次の理由でクラスの動作方法を完全に変更できます。 a。主なコードは依存関係の切り替えを決定するのではなく、フレームワークの構成です。 b。スコープは、呼び出し元のメンバーによって制御されていないときに変更される可能性があり、代わりに静的フレームワークによって外部で決定されます。 したがって、クラスの構成は実際には閉じられていません。サードパーティのツールの構成に基づいて変更されます。 これが質問である理由は、私が必ずしもすべてのIOCコンテナのマスターではないからです。また、IOCコンテナーのアイデアは素晴らしいものの、実装が不十分なことを覆い隠す外観にすぎません。しかし、外部のスコープ制御、プライベートメンバーアクセス、および遅延読み込みを実現するには、多くの重要な疑問の余地のある作業を継続する必要があります。AOPは素晴らしいですが、IOC Containersを介して達成される方法にも疑問があります。 私は、C#と.NET GCが期待どおりに動作することを信頼できます。しかし、コンパイルされたコードを変更して、手動で実行できないことに対する回避策を実行するサードパーティ製のツールに同じ信頼を置くことはできません。 EG:Entity Frameworkと他のORMは、厳密に型指定されたオブジェクトを作成してデータベースエンティティにマッピングし、CRUDを実行するための基本的な機能を提供します。誰でも独自のORMを構築し、OOP / SOLID原則を手動で従うことができます。しかし、これらのフレームワークは私たちを助けてくれるので、毎回車輪を再発明する必要はありません。一方、IOC Containersは、OOP / SOLID原則を意図的に回避し、それを隠すのに役立つようです。

7
SOLIDに切り替えた後、大幅に増加したクラスの数を管理および整理しますか?
ここ数年、私たちは少しずつ一歩ずつ、より良い記述コードに徐々に切り替えてきました。私たちはついに、少なくともSOLIDに似たものへの切り替えを始めていますが、まだまだそこにはありません。切り替えを行って以来、開発者からの最大の不満の1つは、以前はすべてのタスクで開発者が5〜10個のファイルを操作するだけで十分だった数十個のファイルをピアレビューおよびトラバースできないことです。 切り替えを開始する前に、アーキテクチャは次のように編成されていました(1〜2桁以上のファイルが付与されています)。 Solution - Business -- AccountLogic -- DocumentLogic -- UsersLogic - Entities (Database entities) - Models (Domain Models) - Repositories -- AccountRepo -- DocumentRepo -- UserRepo - ViewModels -- AccountViewModel -- DocumentViewModel -- UserViewModel - UI ファイルに関しては、すべてが非常に線形でコンパクトでした。明らかにコードの重複、密結合、および頭痛の種がたくさんありましたが、誰もがそれを横断して理解することができました。完全な初心者、つまりVisual Studioを開いたことのない人は、わずか数週間でそれを理解できました。全体的なファイルの複雑さの欠如により、初心者の開発者や新規採用者も、あまり時間をかけずに貢献を始めることが比較的簡単になります。しかし、これはコードスタイルの利点が出てこないところです。 コードベースを改善するためのあらゆる試みを心から支持しますが、このような大規模なパラダイムシフトについて、チームの他のメンバーからプッシュバックを得るのは非常に一般的です。現在の最大のこだわりのポイントは次のとおりです。 単体テスト クラス数 ピアレビューの複雑さ ユニットテストは時間の無駄だと信じており、個々のコードよりも全体としてコードをはるかに迅速に処理テストできると信じているため、チームにとっては信じられないほど難しい販売でした。SOLIDの承認として単体テストを使用することはほとんど無益であり、この時点ではほとんど冗談になりました。 クラス数はおそらく克服すべき最大のハードルです。5〜10個のファイルを使用していたタスクは、70〜100個かかるようになりました。これらの各ファイルにはそれぞれ異なる目的がありますが、膨大な量のファイルが圧倒される場合があります。チームからの反応は、主にうめき声と頭を掻くものでした。以前は、タスクには1つまたは2つのリポジトリ、1つまたは2つのモデル、ロジックレイヤー、およびコントローラーメソッドが必要でした。 単純なファイル保存アプリケーションを構築するには、ファイルが既に存在するかどうかを確認するクラス、メタデータを書き込むクラスDateTime.Now、ユニットテストの時間を注入できるように抽象化するクラス、ロジックを含むすべてのファイルのインターフェイス、ファイルがあります各クラスの単体テストと、DIコンテナにすべてを追加するための1つ以上のファイルを格納します。 中小規模のアプリケーションの場合、SOLIDは非常に簡単に販売できます。誰もが保守性の利点と容易さを理解しています。ただし、非常に大規模なアプリケーションでは、SOLIDの価値提案が見られないだけです。だから私は、組織と管理を改善して、成長する痛みを乗り越える方法を見つけようとしています。 最近完了したタスクに基づいて、ファイルボリュームの例を少し強くしたいと思いました。ファイル同期要求を受信するために、新しいマイクロサービスのいずれかに機能を実装するタスクが与えられました。要求が受信されると、サービスは一連の検索とチェックを実行し、最終的にドキュメントをネットワークドライブと2つの個別のデータベーステーブルに保存します。 ドキュメントをネットワークドライブに保存するには、いくつかの特定のクラスが必要でした。 - …

8
LSP vs OCP / Liskov Substitution VS Open Close
私は、OOPの固い原則を理解しようとしていますが、LSPとOCPにはいくつかの類似点があるという結論に達しました(詳しくは言いませんが)。 オープン/クローズの原則には、「ソフトウェアエンティティ(クラス、モジュール、関数など)は拡張のために開かれているが、変更のために閉じられている必要があります」と記述されています。 簡単な言葉で言えば、LSPはのFooインスタンスをBar派生元のインスタンスに置き換えることができFoo、プログラムはまったく同じように機能することを示しています。 私はプロのOOPプログラマーではありませんが、LSPはBar、から派生しFooたものがその中の何も変更せず、拡張する場合にのみ可能であるように思われます。つまり、特定のプログラムのLSPはOCPが真の場合にのみ真であり、OCPはLSPが真の場合にのみ真です。それは、それらが等しいことを意味します。 私が間違っている場合は修正してください。これらのアイデアを本当に理解したいです。答えてくれてありがとう。


7
依存関係反転の原則を適用しない場合
現在、SOLIDを把握しようとしています。したがって、依存関係反転の原則は、任意の2つのクラスが直接ではなく、インターフェースを介して通信することを意味します。例:class Aメソッドがあり、typeのオブジェクトへのポインターを予期するclass B場合、このメソッドは実際にtypeのオブジェクトを予期する必要がありますabstract base class of B。これは、オープン/クローズにも役立ちます。 私が正しく理解していれば、私の質問は、これをすべてのクラスの相互作用に適用するのが良い習慣であるか、レイヤーの観点から考えてみるべきですか? 私が懐疑的である理由は、この原則に従うためにいくらかの代価を払っているからです。たとえば、featureを実装する必要がありますZ。分析後Z、機能はA、Bおよびで構成されていると結論付けCます。私が作成ファサードクラスはZ、それは、インタフェースを介して、クラスを使用していますA、BとC。私は実装をコーディングを開始し、いくつかの点で私は、そのタスクを実現するZ実際の機能で構成されA、BそしてD。次に、Cインターフェイス、Cクラスプロトタイプを破棄し、Dインターフェイスとクラスを個別に記述する必要があります。インターフェイスがなければ、クラスのみを置き換える必要があります。 つまり、何かを変更するには、1。呼び出し元2.インターフェイス3.宣言4.実装を変更する必要があります。Python直接結合実装では、実装のみを変更する必要があります。

7
固い原則とヤグニ
ソリッド原則はいつYAGNIになりますか? プログラマとして、複雑さ、保守性、構築時間などの間で常にトレードオフを行います。とりわけ、選択を行うための最も賢明なガイドラインの2つは、SOLID原則とYAGNIです。必要ない場合; ビルドせず、クリーンに保ちます。 たとえば、SOLIDのダイムキャストシリーズを見ると、かなり単純なプログラムとして始まり、非常に複雑なプログラムになります(最後にはい複雑さも見る人の目にあります)。私は不思議に思う:いつ固い原則はあなたが必要としない何かに変わるのか?すべての堅固な原則は、後の段階で使用して変更を加えることを可能にする作業方法です。しかし、解決すべき問題が非常に単純で、使い捨てのアプリケーションである場合はどうでしょうか?または、SOLID原則は常に適用されるものですか? コメントで尋ねられたように: 固い原則 ヤグニ

3
SOLID Principlesのプログラミング
時間が経つにつれて、SOLIDの 2つの部分、「S」と「O」を理解できました。 「O」–継承と戦略パターンの助けを借りて、オープンクローズドプリンシプルを学びました。 “ S” – ORMの学習中に単一責任の原則を学習しました(永続化ロジックはドメインオブジェクトから取り除かれます)。 同様に、SOLIDの他の部分(「L」、「I」、「D」)を学習するのに最適な領域/タスクは何ですか? 参照資料 msdn-C#でのSOLID原則違反の危険性 channel9-.NET / C#でのSOLID Principlesの適用 OOPS原則(固体原則)

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