いつ継承を使用するか、「ブール値フィールドのみ」を使用するか?


18

Railsアプリケーションでは、通知を追加しています。これらの一部は次のとおりblockingです。リソースに関する情報が欠落しているため、追加されたリソースの進行を停止します。

他の通知は単純な通知であり、情報のみを提供します。

今日、私たちのチームの別のプログラマーと話し合いました。次のような継承構造を作成しました。

ここに画像の説明を入力してください

しかし、彼は、blocking各通知にブール値を返すメソッドとして追加し、通知親クラス内でブロックしているサブクラスのリストを指定したいだけです。

これらのアプローチの違いはそれほど大きくありません。私のアプローチでは、このリストを指定する必要はなく、ルートクラスをよりクリーンに保ちます。一方、Notification::Blocking現在発生している特別なロジックもそれほど大きくありません。

この問題には、どのような抽象化がより適していますか?


11
親クラスは、その子について決して知るべきではありません。サブクラスのリストを保持する必要があるのはなぜですか?
coteyr

リソースにどのように追加され、どのように進行を停止しますか?
nullの

3
なぜそれほど多くの通知クラスが必要なのですか?通知クラスを1つ作成して、データ型ではなくデータでアクションを実行できるように思えます。
16年

1
@Trisped:右、行動の1つの側面を徹底的なケースリストを持つ基本クラスに移動し、確信を持って勇気を持って、拡張によるカスタマイズのために使用可能な基本クラスを実際に設計していないことを認める場合、すべての動作を基本クラスに移動します
スティーブジェソップ

回答:


35

基本クラスが派生クラスについて知ることを避けたい。新しい派生クラスを作成するたびにリストに追加することを覚えておく必要があるため、密結合を導入し、メンテナンスの頭痛の種です。

また、このクラスを複数のプロジェクトで使用する場合、Notificationクラスを再利用可能なパッケージ/アセンブリに配置することもできなくなります。

単一の基本クラスを実際に使用する場合、これを解決する別の方法は、基本Notificationクラスに仮想プロパティまたはメソッドIsBlockingを追加することです。派生クラスはそれをオーバーライドして、trueまたはfalseを返します。基本クラスが派生クラスを知らなくても、単一クラスのソリューションがあります。


3
この。一箇所で意思決定を行います。クラスとリストの間でブロックしているクラスの知識をばらまかないでください。
candied_orange

これは私がしていることで、非常にうまく機能し、非常に再利用可能です。
coteyr

13

そして、通知親クラス内でブロックしているサブクラスのリストを指定します。

それは非常に奇妙に見え、特定のコードの匂いです。

クラス間の動作に違いがあり、これらすべての通知を同じ方法で処理する場合(つまり、ポリモーフィズムを使用する場合)にサブクラスを提供します。


1
ここでは、「行動」が重要だと思います。それが単なるデータである場合、フィールドは十分な弁別子になるはずです。ポリモーフィズムを使用する理由は振る舞いですが、継承階層を作成するときは常にメンテナンスの複雑さを考慮する必要があります。en.wikipedia.org/wiki/Composition_over_inheritance
-cottsak

7

既存の答えとは逆に、使用するモードを動的に変更する必要がある場合は、ブール型プロパティが最適なオプションであることをお勧めします(たとえば、ブロックするタイプのリストを提供する構成ファイルを介してどちらでもない)。

そうは言っても、この状況でもより良い設計は、Decoratorオブジェクトを使用することです。


1

私が最初に考えたのは「両方」を使用することですが、ブロッキング通知に関して他にどれだけ特別なものがあるかによると思います。

class Notification
 virtual Boolean Blocking{get return false;}

class BlockingNotification inherits Notification
 virtual overrides Boolean Blocking{get return true;}

そのように、n.Blockingまたはn is BlockingNotification(すべて擬似コードで)を使用できますが、クラスにコンテキスト依存のBlocking値を実装させる場合、その値を毎回確認する必要があるため、BlockingNotificationクラスは次のようになります。あまり役に立たない。

いずれにせよ、基本クラスの実装にBlocking派生クラスについて知ってもらいたくないという他の答えに同意します。


0

2つの基本クラスとそれぞれの複数のインスタンスを作成する代わりに、boolを使用して1つの通知クラスを作成し、通知がブロックされているかどうか、および通知をユーザーに伝えるために必要なその他の情報を示します。

これにより、通知の処理と表示に1セットのコードを使用でき、コードの複雑さが軽減されます。

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