3

そのため、アプリケーションが公開するこの公開 API を使用して、顧客がプラグインを作成できるようにしています。この例のために、次のような非常に単純なキーと値のペア システムであるとしましょう。

public interface Key {
  // marker interface, guaranteed unique in some scope
}

public interface KVPService {
  Set<Key> getKeys();
  Object getValue(Key k); // must be a key provided by getKeys() or it blows up
}

Keyここで、公開してはならないいくつかの属性 (データベース ID など) が内部的にあるとしましょう。私が現在行っていることは、次のようなものです。

/** Internal impl of external Key */    
class InternalKey implements Key {
  int getDatabaseId() {
    // do something...
  }
}

/** Internal impl of external KVPService */    
class InternalKVPService implements KVPService {
  // ...

  public Object getValue(Key k) {
    InternalKey ik = (InternalKey) k;
    return getValueFromDBOrWherever(ik.getDatabaseId());
  }

  // ...
}

これは理想的とは言えません。責任を再配置してキャストを回避し、内部/外部カプセル化を維持する方法はありますか?

現実の世界では、これよりもかなり複雑であることに注意してください。同等のKeyものにはかなりのメタデータが添付されており、誰かが単純な値を取得する以外にやりたいことがたくさんあるので、Map.Entry代わりに - のようなオブジェクトを公開するだけでは、必ずしも問題が解決するとは限りません。

私が思いついた唯一のことは、内部キーと外部キーを完全に分離し、Map<Key, InternalKey>. しかし、その場合、DRY に違反するメタデータをコピーするか、DRY に違反する への外部Key委任を行う必要がInternalKeyありMapます。

誰かもっと賢いものを考えられますか?

4

2 に答える 2

1

私はそうは思わない。しかし、なぜタイプキャストが気になるのでしょうか? 潜在的な ClassCastException は実際には発生しません (ユースケースを理解していると仮定します)。キャストには 5 つほどの機械命令しか必要なく、KPService API の呼び出し元から隠されます。

于 2009-08-07T14:52:03.547 に答える
1

私が見たアプローチの 1 つは、すべてのオブジェクト (この場合はキー) に共通のインターフェイスを公開し、UnsupportedOperationException各メソッドに対して単純に をスローする (または何もしない) 基本実装を提供することです。その後、サブクラスの実装がメソッドをオーバーライドして機能を提供します。確かにオブジェクト指向とはあまり似ていませんが、JDK API にいくつかの例があります (例:Iteratorremove()メソッド)。

別のオプション:ビジターパターンを使用して、ダウンキャストせずに各オブジェクトに機能を実行させることができます。例えば

public interface KeyVisitor {
  void visitInternalKey(InternalKey k);
  void visitFooBarKey(FooBarKey k);
}

public interface Key {
  void visit(KeyVisitor kv);
}

public class InternalKey implements Key {
  public void visit(KeyVisitor kv) {
    kv.visitInternalKey(this);
  }
}

ここでの欠点はInternalKey、ビジターの実装がメソッドを呼び出せるようにするために、(少なくともインターフェイスを介して) でメソッドを公開する必要があることです。ただし、パッケージ レベルで実装の詳細を維持することもできます。

于 2009-08-07T14:52:45.150 に答える