4

では、例を示します。パッケージにライブラリがありますHTTP。パッケージなどでライブラリのサブセクションを定義しますHTTP.TCPProtocol。ここで、HTTP パッケージの TCPProtocol を使用したいと考えています。つまり、TCPProtocol 機能を公開する必要があります。同時に、この機能をライブラリのユーザーにエクスポートしないでください。

どうすればいいですか?ライブラリ全体を 1 つのパッケージに押し込みたくはありません。個別のサブパッケージを使用すると、コードがより構造化され、Eclipse でのナビゲーションが容易になるからです。しかし、ブラウジングすると、プロジェクト内で関数を公開する方法が見つかりませんでしたが、それらをプロジェクト外にエクスポートすることはできませんでした。

編集:より良い例を思いつくことができたので、OPを更新しています。

4

3 に答える 3

2

単純なアプローチの 1 つは、「ユーティリティ」メソッドをホワイトリストに登録して、特定の型の呼び出し元インスタンスのみを受け取るようにすることです。

package gameengine;

interface Whitelisted {} // marker

次に、あなたの方法:

public void myMethod(Whitelisted caller, String arg)

そして呼び出すには:

package gameengine.network;

class Foo implements Whitelisted {
...
Someclass.myMethod(this, "foo");
于 2012-07-04T05:19:37.477 に答える
1

依存関係を確認せずに、コミュニティが提供できる唯一の本当のアドバイスは、コードをリファクタリングすることです。ネットワーキング パッケージ内の何かがゲーム エンジンについて知る必要がある場合、抽象化に漏れがあるように見えます。コードを見ずに言うのは難しいです。

于 2012-07-04T05:19:36.823 に答える
1

呼び出し元のクラスをチェックして、不要な呼び出し元をすべてロックアウトします。呼び出し元のクラスは、スタック トレースから取得できます。以下の例では、Bar のインスタンスのみが system.out.println をトリガーし、他のすべてのインスタンスは例外を取得します。この方法でパッケージ レベルのチェックを行うこともできます。許可されているすべての呼び出し元クラス メソッドが公開されていないことを確認してください。そうしないと、間接的に doSomething メソッドを呼び出すことができます。スタックトレースをさらに調べることで、より深いチェックを行うこともできます。

ただし、熟練した開発者は、この問題であなたがしようとすることを回避できることに注意してください. 本当に「安全」なソリューションはありません。

package one.two;

import one.Bar;

public class Foo {

    public void doSomething() {

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StackTraceElement stackTraceElement = stackTrace[2];
        String className = stackTraceElement.getClassName();

        if (Bar.class.getName().equals(className)) {
            System.out.println("jay!");
        } else {
            throw new RuntimeException("not allowed");
        }

    }
}

package one;

import one.two.Foo;

public class Bar {

    void makeCall() {
        new Foo().doSomething();
    }

    public static void main(String[] args) {
        new Bar().makeCall();
    }

}
于 2012-07-04T07:38:25.017 に答える