5

委任パターンを使用して、ファクトリによって作成されたオブジェクトをサードパーティのライブラリにラップしています。最近、ライブラリで保護されたメソッドが基本クラスに追加され、ラッパー クラスが機能しなくなりました。リフレクションに頼らずに良い解決策を持っている人はいますか?

これはサードパーティのライブラリとそのパッケージにあります。

public class Base {
    public void foo();

    protected void bar(); // Newly added
}

これは私自身のパッケージに入っています。

public class MyWrapper extends Base {
    private Base delegate;

    public MyWrapper(Base delegate) {
        this.delegate = delegate;
    }

    public void foo() {
        delegate.foo()
    }

    protected void bar() {
        // Don't know what to do
    }
}

編集:私の元の投稿は明確ではありませんでした。これら 2 つのクラスは異なるパッケージに含まれています。

なぜ委任が必要なのかという質問に答えるために。これは Delegation/Wrapper パターンの典型的な使用例であり、ここでは数行のコードでは説明できません。ライブラリは Base クラスを公開しますが、ファクトリの実際のオブジェクトは Base の派生クラスです。実際のクラスは構成によって異なります。だから私はデリゲートが何であるかわかりません。したがって、ストレートな継承パターンはここでは機能しません。

4

5 に答える 5

1

Baseクラスはインターフェースか抽象クラスのどちらかであるという印象を受けます。その場合、たとえば以下にリストされている 3 つのメソッドのいずれかを使用して、メソッドを実装する必要があります。bar()

補足として、Baseが通常のクラスの場合、何もする必要はありません ( のインスタンスを呼び出すと、MyWrapper.bar()実際にはBase.bar().


親オブジェクトに委譲する

bar()メソッドがサードパーティ API でコールバックとして使用される場合、これは通常良い考えです。

@Override
protected void bar() {
    delegate.bar();
}

何もしない

コンパイル エラーを回避するために、空のメソッドを追加しました。

@Override
protected void bar() {
    // silently ignored
}

例外をスローする

新しいメソッドの使用を厳しく禁止します。

@Override
protected void bar() {
    throw new UnsupportedOperationException("not implemented");
}

補足として、より堅牢な構造は、継承よりも構成を優先して、実装をサードパーティの実装から切り離すことです。たとえば、

public class MyWrapper {    // does not extend Base
    private Base delegate;

    public MyWrapper(Base delegate) {
        this.delegate = delegate;
    }

    public void foo() {
        delegate.foo()
    }

    // does not have to implement bar()
}
于 2013-04-26T13:33:23.980 に答える
0

委任者を基本クラスの実際のインスタンスにする必要がない場合は、その関係を単純に削除できます。

public class MyWrapper {
    private Base delegate;

    public MyWrapper(Base delegate) {
        this.delegate = delegate;
    }

    public void foo() {
        delegate.foo()
    }

}

それがあなたにとってうまくいくかどうかは、あなたの他のコードに大きく依存しており、あなたのニーズは今のところ完全には明らかではありません.

ライブラリが、抽象基本クラスによって実装される public メソッドを提供するインターフェイスを定義する場合、抽象基本クラスから継承せずにそのインターフェイスを賢明に実装できます。これもニーズを満たす可能性があります。

于 2013-04-27T14:07:33.627 に答える