2つの異なるクラスから継承するクラスがある場合、これはサブクラスが(少なくとも)2つのことを自動的に行うことを意味しないのですか?各スーパークラスから1つですか?
複数のインターフェイス継承がある場合、違いはないと思います。
編集:明確にするために、複数のクラスをサブクラス化するとSRPに違反する場合、複数の(マーカーまたは基本インターフェイス(Comparableなど))インターフェイスの実装もSRPに違反すると考えています。
2つの異なるクラスから継承するクラスがある場合、これはサブクラスが(少なくとも)2つのことを自動的に行うことを意味しないのですか?各スーパークラスから1つですか?
複数のインターフェイス継承がある場合、違いはないと思います。
編集:明確にするために、複数のクラスをサブクラス化するとSRPに違反する場合、複数の(マーカーまたは基本インターフェイス(Comparableなど))インターフェイスの実装もSRPに違反すると考えています。
回答:
非常に狭い意味では、答えは「はい」です。基本クラスまたはインターフェースが単一の目的のために設計されていると仮定すると、両方を継承すると、複数の責任を持つクラスが作成されます。ただし、それが「悪いこと」であるかどうかは、継承しているクラスまたはインターフェースの性質に依存します。
クラスとインターフェースを2つの主要なグループに分割できます-システムの本質的な複雑性に対処するものと、偶発的な複雑性に対処するものです。複数の「本質的な複雑さ」クラスから継承する場合、それは悪いです。1つの「必須」クラスと1つ以上の「偶発的な」クラスから継承する場合は問題ありません。
たとえば、請求システムでは、請求書と請求サイクルを表すクラス(本質的な複雑性に対処する)と永続オブジェクト(偶発的な複雑性に対処する)のクラスを作成できます。このように継承する場合
class BillingCycleInvoice : public BillingCycle, public Invoice {
};
それは悪いことですBillingCycleInvoice
。システムの本質的な複雑さに関連して、あなたには責任があります。
一方、このように継承する場合
class PersistentInvoice : public Invoice, public PersistentObject {
};
あなたのクラスは大丈夫です。技術的には、一度に2つの懸念に対応しますが、そのうちの1つだけが必須であるため、偶然の1つを「ビジネスのコスト」として引き継ぐことができます。
SRPは、悪い神クラスを避けるためのガイドラインですが、文字通りあまりにも取ることができ、プロジェクトは、ほんの一握りの組み合わせなしでは実際には何もできないクラスのトンでバルーンを開始します。複数の継承/複数のインターフェースは、クラスが大きくなりすぎている兆候かもしれませんが、目の前のタスクに対して焦点が非常にきめ細かすぎて、ソリューションが過剰に設計されている兆候かもしれません。多重継承の有効なユースケースであり、あなたの心配は根拠がありません。
ソフトウェア設計は科学と同じくらい芸術であり、多くの競合する利益のバランスのとれた行為です。私たちには、問題を引き起こす一方向への遠いことを回避するためのルールがありますが、それらのルールは、最初に回避しようとしていたものと同じくらい悪いか悪い場所に私たちを連れて行くことができます。
幾分。SRPの主な原則に注目しましょう。
クラスに変更する理由は1つだけです。
多重継承はこれを強制しませんが、それにつながる傾向があります。クラスがその基本クラスをオーバーライドまたは実装する場合、それが変更されるより多くの理由になる傾向があります。このように、インターフェイスの多重継承は、クラスの継承よりも厄介になる傾向があります。2つのクラスが継承されているがオーバーライドされていない場合、変更する理由は新しいクラスではなく基本クラスに存在します。
多重継承がSRPに違反しない場所は、1つを除くすべての基本型がクラスが実装しているものではなく、クラスがたまたま持っている特性として機能する場合です。IDisposable
C#で検討してください。使い捨てのものには2つの責任はありません。インターフェースは、特性を共有するが明らかに責任が異なるクラスのビューとして機能するだけです。
どういたしまして。Javaでは、たとえばFooなど、何らかのドメインオブジェクトを表すインターフェイスを使用できます。他のFooオブジェクトと比較する必要がある場合があるため、Comparableを実装します(Comparatorクラスで外部化された比較ロジックを使用)。ネットワークを介して転送できるように、このオブジェクトもSerializableである必要がある場合があります。また、クローン可能にする必要があります。したがって、クラスは3つのインターフェイスを実装しますが、Fooでサポートされているものを超えるロジックをサポートするためのロジックはありません。
とはいえ、SRPを極限まで使用するのはばかげています。クラスが複数のメソッドを定義している場合、SRPに違反していますか?すべてのJavaオブジェクトには、toString()メソッドとequals(Object)メソッドがあります。これは、Javaのすべてのオブジェクトが等式と自己表現の両方を担当することを意味します。それは悪いことですか?