の具体的な実装を知っている場合P
、つまり、どこかから提供されていない場合は、ビジターパターンを使用できます。
abstract class P {
int p1;
int p2;
abstract void visit(final PVisitor visitor);
}
class P1 extends P {
int p3;
int p4;
@Override
void visit(PVisitor visitor) {
visitor.doStuff(this);
}
}
class P2 extends P {
int p5;
int p6;
@Override
void visit(PVisitor visitor) {
visitor.doStuff(this);
}
}
interface PVisitor {
void doStuff(P1 p);
void doStuff(P2 p);
}
したがってCollection<PVisitor>
、ビジターロジックがあり、sをP
使用してインスタンスにアクセスするPVisitor
と、ポリモーフィズムによって何が何であるかがわかります。
編集
OPのコメントに続いて、私はアイデアを思いつきました。
ビジターパターンといくつかのジェネリックスを組み合わせた抽象的なファクトリパターンについてはどうでしょうか。
新しいタイプを追加する場合はHandler
、何かを変更する必要があることを私たちは知っているという考え方です。論理的には、それはHandlerFactory
実装であり、P
sではありません。abstract HandlerFactory
があり、各P
実装がそれを処理するインスタンスを返す責任がある場合はどうなりますか。
ファクトリには、特定のハンドラーなどを返すいくつかのメソッドがありますgetDatabaseHandler
。これらHandler
は、ジェネリックHandler
クラスから継承できます。
アイデアは次のようになります。
abstract class P {
int p1;
int p2;
public abstract HandlerFactory<? extends P> getHandlerFactory();
}
class P1 extends P {
int p3;
int p4;
@Override
public HandlerFactory<P1> getHandlerFactory() {
return new P1HandlerFactory(this);
}
}
class P2 extends P {
int p5;
int p6;
@Override
public HandlerFactory<? extends P> getHandlerFactory() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
abstract class HandlerFactory<T extends P> {
private T t;
public HandlerFactory(T t) {
this.t = t;
}
public T getT() {
return t;
}
public abstract DatabaseHandler<T> getDatabaseHandler();
public abstract JMSHandler<T> getJMSHandler();
}
abstract class Handler<T extends P> {
private final T t;
public Handler(T t) {
this.t = t;
}
public T getT() {
return t;
}
}
abstract class DatabaseHandler<T extends P> extends Handler<T> {
public DatabaseHandler(T t) {
super(t);
}
public abstract void persist(Connection con);
}
abstract class JMSHandler<T extends P> extends Handler<T> {
public JMSHandler(T t) {
super(t);
}
public abstract void send();
}
class P1HandlerFactory extends HandlerFactory<P1> {
public P1HandlerFactory(P1 t) {
super(t);
}
@Override
public DatabaseHandler<P1> getDatabaseHandler() {
return new P1DatabaseHandler(getT());
}
@Override
public JMSHandler<P1> getJMSHandler() {
return new P1JMSHandler(getT());
}
}
class P1DatabaseHandler extends DatabaseHandler<P1> {
public P1DatabaseHandler(P1 p1) {
super(p1);
}
@Override
public void persist(Connection con) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
class P1JMSHandler extends JMSHandler<P1> {
public P1JMSHandler(P1 p1) {
super(p1);
}
@Override
public void send() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
したがって、の各実装にP
はコンパニオンが付属しておりHandlerFactory
、の新しい実装を追加するには、の実装P
のみが必要HandlerFactory
です。ジェネリックスを使用すると、たとえば、P1A
変更が必要ない場合は、P1B
から継承しP1
てaを使用できます。P1Handler
新しいタイプHandler
が追加された場合、そのタイプを取得するためのメソッドを持つようにすべてのHandlerFactory
実装を変更する必要がありますHandler
が、P
sを変更する必要はありません。
使用法は次のようになります
final P1 p1 = new P1();
final DatabaseHandler<P1> databaseHandler = p1.getHandlerFactory().getDatabaseHandler();
したがって、そのインスタンスからインスタンスの特定のデータベースハンドラーを取得できます。