3


0

最終クラスのサブクラス化。または、縮退デコレータ

同じ種類のオブジェクトのさまざまな表現があります。それを「モノ」と呼びましょう。 「モノ」はマーカーインターフェイスです。 ThingFormat0、ThingFormat1、ThingFormat2など Thingを実装するすべてのJavaBeanです。 (これらはJavaBeansであるため、JSONマーシャラーは自動的にJSONとの間でそれらを自動的に変換します。)ThingFormat1には、名前やIDなどの少数のメンバーしかありません。 ThingFormat2には、他のものへのURIリンクがあります。 ThingFormat3には、これらの他のものなどのThingFormat1表現があります。

JSONシリアライザーは、URIを自動的に変換する方法を知っています。 (toString()およびコンストラクターClassName(String string)を使用して変換できる任意のクラスで機能します。)

URIのように動作するが、マーカーインターフェイスThingを実装するThingFormat0が必要です。

public class ThingFormat0 extends URI implements Thing {}

URIは最終クラスであり、サブクラス化できないため、これは機能しません。

これを行うために考えられる唯一の方法は、デコレータを作成することです(URIに機能を追加しないため、デコレータの非常に退化した種類です)。 URIをラップし、必要なURIのすべてのメソッドを実装する必要があるため、これは一部の「アヒル型」言語では簡単ですが、Javaでの苦痛が大きくなります。 もっと簡単な方法はありますか?

5 Answer


3


私が考えることができる2つの簡単な方法:

  • Eclipseを使用する場合、任意のフィールドにデリゲートメソッドを使用できます 自動的に生成されます。

  • URIのソースをThingURIという名前の新しいクラスにコピーします。


2


クラスが継承の代わりに構成を使用できない理由はありますか?

public class ThingFormat0 implements Thing {
  private final URI uri;

  public ThingFormat0(String uri) { this.uri = URI.create(uri); }

  public ThingFormat0(URI uri) { this.uri = uri; }

  public URI getUri() { return uri; }

  @Override public String toString() {
    return uri.toString();
  }
}


1


最終クラスをサブクラス化することはできません。 期間。

URIの場合、セキュリティ上の理由からほぼ間違いなく最終的なものです。つまり 誰かがサンドボックスのセキュリティを破るのを防ぐために、たとえば、アクセスコントロールを破壊できるようにするURIの卑劣なサブタイプを提供します。

そのため、ラッパーまたはデコレーターなどを使用する必要があります。


0


// base class that handles delegation
class BaseThing implements Thing {

   BaseThing(String uri) { ... }

   BaseThing(URI uri) { ... }

   URI getURI() { ... }

   ...
}

class ThingFormat0 extends BaseThing {
   ...
}


0


あなたの `ThingFormat`型はURIではないので、これを見つけるのは難しいです。 URIを公開し、URIに対応できますが、URIにすることはできません。 おそらく_implementation inheritance_を固定していますが、これは適切な_is-a_関係ではないため、interface inheritance_はここで失敗します。 _LSPに失敗します。

たとえば、「ThingFormat」にスキームまたはフラグメントコンポーネントがあるかどうか、または何らかのベースURIに対して解決できるかどうかを検討します。 これらは、たまたま「ThingFormat」とは関係のないURIのファセットと操作です。