タグ付けされた質問 「single-responsibility」

単一責任の原則では、システム内の各モジュールは単一の機能または機能、まとまりのある機能の集約に責任を負うべきであると述べています。別の一般的な言い方をすれば、各モジュールは変更する理由が1つだけあるべきだということです。

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のコンテキストで責任をどのように定義しますか?

12
引数を検証するコンストラクターはSRPに違反しますか?
私は可能な限り単一責任原則(SRP)に準拠しようとしていますが、デリゲートに大きく依存する特定のパターン(メソッドのSRP)に慣れました。このアプローチが適切かどうか、または深刻な問題があるかどうかを知りたいです。 たとえば、コンストラクターへの入力を確認するために、次のメソッドを導入できます(Stream入力はランダムで、何でも可能です) private void CheckInput(Stream stream) { if(stream == null) { throw new ArgumentNullException(); } if(!stream.CanWrite) { throw new ArgumentException(); } } このメソッドは(おそらく)複数のことを行います 入力を確認する さまざまな例外をスローする したがって、SRPを順守するために、ロジックを private void CheckInput(Stream stream, params (Predicate<Stream> predicate, Action action)[] inputCheckers) { foreach(var inputChecker in inputCheckers) { if(inputChecker.predicate(stream)) { inputChecker.action(); } } } たぶん1つのことだけを行う(行うのか?):入力を確認する。入力の実際のチェックと例外のスローのために、次のようなメソッドを導入しました bool …

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

11
このクラス設計は単一の責任原則に違反していますか?
今日、誰かと議論がありました。 私は貧血領域モデルとは対照的に、豊富な領域モデルを持つことの利点を説明していました。そして、次のような単純なクラスでポイントをデモしました。 public class Employee { public Employee(string firstName, string lastName) { FirstName = firstName; LastName = lastname; } public string FirstName { get private set; } public string LastName { get; private set;} public int CountPaidDaysOffGranted { get; private set;} public void AddPaidDaysOffGranted(int numberOfdays) { // Do stuff } …

7
単一責任の原則-コードの断片化を回避する方法
私は、チームリーダーがSOLID開発原則の熱心な支持者であるチームに取り組んでいます。しかし、彼は複雑なソフトウェアをドアから取り出すのに多くの経験を欠いています。 すでに非常に複雑なコードベースであったものにSRPを適用した状況があり、現在では非常に断片化されており、理解とデバッグが困難になっています。 現在、コードの断片化だけでなく、プライベートまたは保護されている可能性のあるクラス内のメソッドが「変更の理由」を表すと判断され、パブリックまたは内部クラスおよびインターフェースに抽出されているため、カプセル化にも問題がありますアプリケーションのカプセル化の目標に沿っていない。 20を超えるインターフェイスパラメーターを受け取るクラスコンストラクターがいくつかあるため、IoCの登録と解決はそれ自体が怪物になりつつあります。 これらの問題のいくつかを修正するために使用できる「SRPからのリファクタリング」アプローチがあるかどうかを知りたいです。私は、いくつかの密接に関連するクラスを「ラップ」してそれらの機能の合計への単一のアクセスポイントを提供する多数の空の粗いクラスを作成する場合、SOLIDに違反しないことを読んだ過度にSRPされたクラスの実装)。 それとは別に、誰もが幸せなまま、開発努力を実践的に続けることを可能にする解決策は考えられません。 助言がありますか ?

8
「神のオブジェクト」が間違っていることを証明または反証するにはどうすればよいですか?
問題の概要: 長い話を簡単に言えば、私はコードベースと開発チームを引き継ぎました。私はこれを置き換えることは許されておらず、God Objectsの使用は大きな問題です。今後、リファクタリングをしてもらいたいのですが、「もっと簡単だから」、God Objectsを使ってすべてをやりたいチームから押し戻されています。これは、リファクタリングが許可されないことを意味します。私は長年の開発経験、これらのことを知るために雇われた新しいボスなどを押し返しました。また、サードパーティのオフショア会社が営業担当者を説明しました。これは現在、役員レベルと会議です明日であり、長期的にはより安くなると思うので、多くの技術的な弾薬を使ってベストプラクティスを提唱したいと思います(そして、個人的にはサードパーティが心配していることだと感じています)。 私の問題は技術レベルからのものであり、長期的にはよく知っていますが、超短期間と6か月の期間には問題があります。 1人(ロバートC.マーティン、別名ボブおじさん)の、1人のデータ(1人のみ)(ロバートCマーティン)が十分な議論をしていないと言われているように。 質問: 「神」オブジェクト/クラス/システムのこの使用は明らかに悪いと言っている分野の有名な専門家が直接引用できるリソース(タイトル、発行年、ページ番号、引用)は何ですか?最も技術的に有効なソリューションの場合)? 私がすでに行った研究: ここにはたくさんの本があり、「god object」と「god class」という言葉の使用についてインデックスを検索しました。奇妙なことに、ほとんど使用されておらず、たとえば、私が持っているGoF本のコピーは使用されません(少なくとも私の目の前のインデックスによると)が、下の2冊の本で見つけましたが、もっと欲しい私は使えます。 ウィキペディアのページで「God Object」と現在の参照リンクの少ないスタブを確認したので、個人的には有効とは見なされない環境ではあまり使用できないと言うことには個人的に同意します。引用された本はまた、私がこれらの技術的ポイントを議論している人々によって有効であるには古すぎると考えられています。 「オブジェクトは使いやすい」。私は個人的にこの声明が間違っていると信じていますが、それが何であれ真実を証明したいと思います。 ロバートCマーティンの「C#のアジャイルの原則、パターン、および実践」(ISBN:0-13-185725-8、ハードカバー)では、266ページに「神のクラスが悪い考えであることを誰もが知っています。システムのすべてのインテリジェンスを単一のオブジェクトまたは単一の機能に集中させること。OODの目標の1つは、動作を多数のクラスおよび多数の機能に分割および分散することです。-そして、とにかく時々神のクラスを使用する方が良いことを時々言い続けます(例としてマイクロコントローラーを引用)。 ロバートCマーティンの「クリーンコード:アジャイルソフトウェアクラフツマンシップハンドブック」136ページ(およびこのページのみ)で、「神のクラス」について説明し、「クラスは小さくなければならない」ルールの違反の主な例として呼び出しています彼は138ページから始まる単一責任原則の推進に使用しています。 私が抱えている問題は、すべての参考文献と引用が同じ人(ロバートC.マーティン)から来ており、同じ一人の人/情報源から来ていることです。彼はただ一つの見解であるため、「神クラス」を使用しないという私の願望は無効であり、ソフトウェア業界の標準的なベストプラクティスとして受け入れられないと言われています。これは本当ですか?ボブおじさんの教えを守ろうとすることで、技術的な観点から間違ったことをしているのでしょうか? 神のオブジェクトとオブジェクト指向プログラミングおよび設計: これについて考えるほど、OOPを勉強するときに学ぶことが多くなり、明示的に呼び出されることはありません。良いデザインへのその暗黙は私の考えです(私が学びたいので、自由に訂正してください)、問題は私がこれを「知っている」ことですが、誰もがそうではありません。統計的にほとんどの人はプログラマーではないため、実際にはほとんどの人が統計的に無知であるにもかかわらず、私は事実上それを普遍的な真実と呼んでいます。 結論: 彼らが技術的な主張をしており、真実を知り、実際のエンジニア/科学者のような引用でそれを証明できるようにしたいので、引用する最良の追加結果を得るために何を検索するのか迷っています私は、神のオブジェクトを使用したコードの個人的な経験のために、神のオブジェクトに偏っています。どんな援助または引用も深く感謝されるでしょう。

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
クラスの本当の責任は何ですか?
私は、OOPの名詞に基づいた動詞を使用することが合法かどうか疑問に思っています。 私はこの素晴らしい記事に出くわしましたが、それが主張する点にはまだ賛成しません。 この問題をもう少し説明するために、この記事では、たとえばFileWriterクラスが存在するべきではないと述べていますが、書き込みはアクションなので、クラスのメソッドである必要がありFileます。RubyプログラマーはFileWriterクラスの使用に反対する可能性が高い(RubyはメソッドFile.openにファイルへのアクセスを使用する)のに対し、Javaプログラマーはそうではないため、多くの場合言語に依存していることに気付くでしょう。 私個人の(そしてもちろん、非常に謙虚な)視点は、そうすることは単一責任の原則を破ることだということです。PHPでプログラミングしたとき(PHPは明らかにOOPに最適な言語だからです)、この種のフレームワークをよく使用します。 <?php // This is just an example that I just made on the fly, may contain errors class User extends Record { protected $name; public function __construct($name) { $this->name = $name; } } class UserDataHandler extends DataHandler /* knows the pdo object */ { public function …

10
単一責任の原則の適用可能性
私は最近、一見些細な建築上の問題に直面しました。私のコードには、次のように呼ばれるシンプルなリポジトリがありました(コードはC#です): var user = /* create user somehow */; _userRepository.Add(user); /* do some other stuff*/ _userRepository.SaveChanges(); SaveChanges データベースへの変更をコミットするシンプルなラッパーでした: void SaveChanges() { _dataContext.SaveChanges(); _logger.Log("User DB updated: " + someImportantInfo); } その後、しばらくして、システムでユーザーが作成されるたびに電子メール通知を送信する新しいロジックを実装する必要がありました。システムへの呼び出し_userRepository.Add()とSaveChangesシステムの呼び出しが多数あったため、次のSaveChangesように更新することにしました。 void SaveChanges() { _dataContext.SaveChanges(); _logger.Log("User DB updated: " + someImportantInfo); foreach (var newUser in dataContext.GetAddedUsers()) { _eventService.RaiseEvent(new UserCreatedEvent(newUser )) } …

8
更新メソッドに戻り型を追加すると、「単一責任の原則」に違反しますか?
データベース内の従業員データを更新する方法があります。Employee「更新」オブジェクト手段は、実際に新しいオブジェクトをインスタンス化するためのクラスは、不変です。 UpdateメソッドにEmployee更新されたデータを含む新しいインスタンスを返すようにしたいのですが、メソッドの責任は従業員データを更新し、データベースから新しいオブジェクトを取得Employeeすることであると言えますが、単一責任原則に違反しますか? DBレコード自体が更新されます。次に、このレコードを表す新しいオブジェクトがインスタンス化されます。

11
各クラスの責任が1つだけであることを確認してください、なぜですか?
Microsoftのドキュメント、WikipediaのSOLIDプリンシペ記事、またはほとんどのITアーキテクトによると、各クラスに1つの責任のみを持たせる必要があります。誰もがこの規則に同意するように見える場合、誰もこの規則の理由について同意するように思われないので、私はその理由を知りたいです。 メンテナンスの改善を挙げている人もいれば、簡単なテストを提供したり、クラスをより堅牢にしたり、セキュリティを強化したりする人もいます。何が正しいのか、実際にはどういう意味ですか?なぜメンテナンスが改善され、テストが簡単になり、コードがより堅牢になるのですか?

8
クラスが単一の責任原則を満たしているかどうかを判断する方法は?
単一責任の原則は、高い結束の原則に基づいています。この2つの違いは、SRPに準拠するクラスの責任は1つだけであるのに対し、非常に凝集性の高いクラスには密接に関連する一連の責任があることです。 しかし、特定のクラスに一連の責任があり、したがって非常に凝集性があるのか​​、それとも1つの責任しか持たず、したがってSRPに準拠するのかをどのように判断するのでしょうか。言い換えれば、クラスが非常にきめ細かいと考える人もいるかもしれません(クラスがSRPに準拠していると考える人もいるかもしれませんが)

12
「Do One Thing」パラダイムが有害になるのはいつですか?
この投稿を改善したいですか?引用や回答が正しい理由の説明など、この質問に対する詳細な回答を提供します。十分な詳細のない回答は、編集または削除できます。 この質問は、Software Engineering Stack Exchangeで回答できるため、Stack Overflowから移行されました。 8年前に移行され ました。 引数のために、指定されたファイルの内容を行ごとに出力するサンプル関数を次に示します。 バージョン1: void printFile(const string & filePath) { fstream file(filePath, ios::in); string line; while (std::getline(file, line)) { cout << line << endl; } } 関数は、抽象化の1つのレベルで1つのことを行うことが推奨されることを知っています。私にとっては、上記のコードはほとんど1つのことを行い、かなりアトミックです。 一部の書籍(Robert C. MartinのClean Codeなど)では、上記のコードを個別の機能に分割することを提案しているようです。 バージョン2: void printFile(const string & filePath) { fstream file(filePath, ios::in); printLines(file); } void …

10
単一責任原則を新しいコードに適用できますか/適用すべきですか?
原則は変更する1つの理由があるモジュールとして定義されます。私の質問は、確かにこれらの変更理由は、コードが実際に変更を開始するまでわからないということですか?ほとんどすべてのコードには、変更される可能性がある多くの理由がありますが、これらすべてを確実に予測し、これを念頭に置いてコードを設計しようとすると、非常に貧弱なコードになります。コードを変更する要求が入り始めたときにのみ、SRPの適用を実際に開始することをお勧めしますか?より具体的には、1つのコードが複数の理由で複数回変更された場合に、変更する理由が複数あることを証明します。変更の理由を推測しようとすると、非常に反アジャイルに聞こえます。 例は、ドキュメントを印刷するコードです。それをPDFに印刷するように変更する要求が来てから、ドキュメントにいくつかの異なるフォーマットを適用するように変更するために2番目の要求が行われます。この時点で、変更する理由(およびSRP違反)が複数あることを示す証拠があり、適切なリファクタリングを行う必要があります。


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