2

class の実装がいくつかBaseあり、すべてのオブジェクトはList<Base>.

詳細なチェックを使用せずactionに、これらのオブジェクトに基づいて特定のものを呼び出すにはどうすればよいですか? これらのオブジェクトのインスタンスに基づいて実行するサービスメソッドを選択するにはどうすればよいでしょうか。ただし、アクションが実行されるオブジェクトを気にする必要はありません。適切なサービス メソッドは、型ケースや instanceof チェックなしで何らかの形で自動的に選択される必要があります。instanceofinstanceof

class Base;
class Foo extends Base;
class Bar extends Base;

class Service {
    List<Base> bases;

    public void someMethod() {
        for (Base base : bases) {
            //perform some instanceof dependend action.
            //these actions cannot be inside of any Base class as it makes use of other objects too.
            if (base instanceof Foo) {
                fooService.action((Foo) base);
            }
            if (base instanceof Bar) {
                barService.action((Bar) base);
            }
        }
    }
}


//custom service methods
class FooService {
    void action(Foo foo) {
    }
}

class BarService {
    void action(Bar bar) {
    }
}
4

3 に答える 3

4

ポリモーフィズムは 1 つの可能性です。Base クラスに抽象 action() メソッドが含まれている場合は、if ステートメントを使用せずに直接呼び出すことができます。

もう一つはレジストリです。Base のサブクラスごとに、サービス クラスへのマッピングを登録できます。someMethod() で、レジストリ内のクラスを検索し、対応するサービス クラスを取得して呼び出します。

ところで、instanceof ステートメントの問題は冗長性だけではありません。これらを使用して記述したコードは、Base の新しいサブクラスが作成されるとすぐに壊れる可能性があります。オープン/クローズドの原則を満たすことで、コードの脆弱性を軽減できます。

于 2013-04-01T00:32:34.677 に答える
2

Visitor考えられる解決策の 1 つは、パターンを使用することです。FooService両方のオーバーロードされたメソッドを使用して、とBarServiceを 1 つのクラスに結合する必要がありaction()ます。次に、およびクラスaccept()のそれぞれにメソッドを追加して、適切なメソッドを呼び出せるようにする必要があります。詳細については、http://en.wikipedia.org/wiki/Visitor_patternを参照してください。FooBaraction()

この問題を解決できる他のより適切な設計パターンが存在する可能性があります。それらについて勉強することをお勧めします。

于 2013-04-01T00:32:24.770 に答える