インターフェイス(継承ではない)または何らかの種類のプロパティメカニック(リソース記述フレームワークのように機能するものでさえ)を使用する必要があります。
それで
interface Colored {
Color getColor();
}
class ColoredBook extends Book implements Colored {
...
}
または
class PropertiesHolder {
<T> extends Property<?>> Optional<T> getProperty( Class<T> propertyClass ) { ... }
<V, T extends Property<V>> Optional<V> getPropertyValue( Class<T> propertyClass ) { ... }
}
interface Property<T> {
String getName();
T getValue();
}
class ColorProperty implements Property<Color> {
public Color getValue() { ... }
public String getName() { return "color"; }
}
class Book extends PropertiesHolder {
}
明確化(編集):
エンティティクラスにオプションフィールドを追加するだけ
特にOptional-wrapperを使用すると(編集:4castleの回答を参照)、これ(元のエンティティにフィールドを追加する)は、小規模で新しいプロパティを追加する実行可能な方法だと思います。このアプローチの最大の問題は、低カップリングに対して機能する可能性があることです。
ブッククラスがドメインモデルの専用プロジェクトで定義されているとします。ここで、ドメインモデルを使用して特別なタスクを実行する別のプロジェクトを追加します。このタスクには、bookクラスの追加のプロパティが必要です。継承(以下を参照)になるか、新しいタスクを可能にするために共通ドメインモデルを変更する必要があります。後者の場合、ブッククラスに追加された独自のプロパティにすべて依存するプロジェクトの束になりますが、ブッククラス自体はこれらのプロジェクトに依存します。追加プロジェクト。
追加のプロパティを提供する方法になると、なぜ継承に問題があるのですか?
サンプルクラス「Book」を見ると、多くの場合、多くのオプションフィールドとサブタイプを持つドメインオブジェクトについて考えます。CDを含む本のプロパティを追加することを想像してください。現在、4種類の本があります。本、カラーの本、CDの本、カラーの本、 CD。この状況をJavaの継承で記述することはできません。
インターフェイスを使用すると、この問題を回避できます。インターフェイスを使用して、特定のブッククラスのプロパティを簡単に構成できます。委任と構成により、希望するクラスを簡単に取得できます。継承を使用すると、通常、クラスにオプションのプロパティがいくつかありますが、それらは兄弟クラスが必要とするために存在します。
継承がしばしば問題の多いアイデアである理由をさらに読む:
継承が一般的にOOP支持者によって悪いものと見なされるのはなぜですか
JavaWorld:拡張が悪である理由
一連のインターフェースを実装して一連のプロパティを構成する際の問題
インターフェースを拡張に使用する場合、それらのごくわずかなセットがある限り、すべては問題ありません。特に、あなたのオブジェクトモデルが他の開発者によって使用され拡張されている場合、例えばあなたの会社でインターフェースの量は増えます。そして最終的に、まったく関係のないユースケースのために、同僚が顧客Xのプロジェクトですでに使用したメソッドを追加する新しい公式の「プロパティインターフェース」を作成することになります。
編集:別の重要な側面はgnasher729によって言及されています。多くの場合、既存のオブジェクトにオプションのプロパティを動的に追加する必要があります。継承またはインターフェイスを使用すると、オプションとはほど遠い別のクラスでオブジェクト全体を再作成する必要があります。
オブジェクトモデルの拡張をその程度まで期待する場合は、動的拡張の可能性を明示的にモデリングすることで改善できます。各「拡張」(この場合はプロパティ)が独自のクラスを持っている上記のようなものを提案します。クラスは、拡張機能の名前空間と識別子として機能します。パッケージの命名規則をそれに応じて設定すると、この方法により、元のエンティティクラスのメソッドのネームスペースを汚染することなく、無制限の拡張が可能になります。
ゲーム開発では、多くのバリエーションで動作とデータを作成したい状況にしばしば遭遇します。これが、アーキテクチャパターンentity-component-systemがゲーム開発サークルでかなり人気を得た理由です。これは、オブジェクトモデルに多くの拡張機能が期待される場合に、見ておきたい興味深いアプローチです。