2011-01-22 17 views
1

外部クラスによって呼び出される必要があるため、メソッドをpublicに設定しましたが、1つまたは2つのメソッドで呼び出す必要があります。他のメソッドによって呼び出されると、自分のプログラムにバグが発生する可能性があります。だから、誤って自分の方法を中心に、プログラミングから私を防ぐために、私は発信者を制限したいの方法の中にこのようなものをやっている:Java - メソッドが呼び出される方法による制限

if(trace.length<2){ 
    throw new Exception("Class should not call its own function."); 
}else if(trace[1].getClassName()!=desiredClassName || trace[1].getMethodName()!=desiredMethodName){ 
    throw new Exception(trace[1].getClassName()+"\" is invalid function caller. Should only be called by "+desiredClassName+"->"+desiredMethodName+"."); 
} 

は私がやるべき何か他のものはありますか私のプログラムの仕組みを忘れてはいけませんか?

+0

javadocsを記述しますか? – BalusC

+0

私はおそらくそれをやるべきではないかと思いますが、不適切な呼び出しを明示的に防ぐように説明したようなプログラムを人々がやっているのか、誰かが私のコード全体に散らばっていると笑ってしまいます。 – schnozzinkobenstein

+0

最も良い解決策は、このメソッドをprivateにして 'friend'メソッドを宣言することですが、これはJavaではなくC++です。あなたがやっていることは時々意味をなさないかもしれませんが、より良い解決策を見つけることを試みます。スタックトレースの作成にはかなりの時間がかかります。したがって、テストを 'assert'に置くことを検討するかもしれません。問題が発生した場合は '-ea'を使用します。 – maaartinus

答えて

4

呼び出しを制限するために可視性を使用する必要があります。メソッドをパブリックにする(またはjavadocingする)ことは、あなたが専門分野を持っていなければ機能しません(そして呼び出し元も制御します)。あなたの説明から、あなたはどちらにもなりません。

あなたができることは、クラスパッケージをプライベートにして、そのクラスの2人の呼び出し元と同じパッケージに入れます。あなたが適切なパッケージ構造を持っている限り、これは動作します。例えば:のみAおよびBによって呼び出されるべき あなたのクラス:

package thepackage.of.a.and.b; 
//imports here 
class CallableByAB { 
public void methodA(){} 
public void methodB(){} 
} 

A:

package thepackage.of.a.and.b; 
public class A { 
    /*...other code here */ 
    new CallableByAB().methodA(); 
    /*...other code here */ 
} 

B:

package thepackage.of.a.and.b; 
public class B { 
    /*...other code here */ 
    new CallableByAB().methodB(); 
    /*...other code here */ 
} 

他のクラスがnew CallableByAB()を呼び出すか、それをインポートすることはできません。したがって、安全性。

3

これは、解決する必要のない問題に対する非常に脆弱な解決策のようです。

この特定のケースでは、将来のメンテナンスではあまり重視されないかもしれません。これらの特別なガードを持つ方法のほんの数例です。しかし、そのようなロジックを大規模なコードベースの多くのメソッドに適用しようとすると想像してください。あなたの場合でも、他のコンテキストでは再利用できないコードを記述しています。

これを行う必要があるという事実は、ある種の誤ったデザインを反映しています。

予期せず呼び出された場合に状態が汚れるような、ある種のステートフルインターフェイスがあると推測します。理想的には、私はインターフェイスをより堅牢なものにしたいと思いますが、それだけでは実行できない場合:このインターフェイスを使用する特定のメソッドがある場合、それらを特定のクラス(おそらく現在のオブジェクトクラスの内部クラス)このクラスでのみハンドルを表示できますか?

private Class TheLegalCaller { 
     private RestrictedCallee myCallee = new RestricatedCallee() ; // or other creation 
     public void doOneThing() { myCallee.doOne(); } 
     public void doOtherThing() } myCallee.doOther(); } 
} 

さて、これで欠点は、あなたがランダムに、私はあなたがまだ問題を持っていると思います間違った場所にTheLegalCaller使う場合にのみ、レベルの問題を押し上げることです。しかし、おそらく制限を非常に目立たせることで、あなたの記憶を助けるでしょうか?

+0

メソッドは、現在含まれているクラスのフィールドへのアクセスを保持する必要がありますが、メソッドを含むクラスによって部分的に構成された別のクラスによってアクセスできる必要があります。私はこのような状況であなたの解決策を適用できないような気がします。私はできますか? – schnozzinkobenstein

+0

私は今あなたの編集を見ています...どのデータ型/構造がTheLegalCallerですか?私は構文を認識しません。 – schnozzinkobenstein

+0

内部クラスはそのクラスを含むメンバーを見ることができるので、これを適用することができます – djna

0

私はそれを行うには非常に簡単な方法を見つけましたが、いくつかの符号化方法論が必要です。

class AllowedCaller { 
    private Object key; 
    public boolean getKey(){ 
    return key; 
    } 
    public void allowedCallingMethod(RestrictedAccessClass rac){ 
    this.key = rac; 
    rac.restrictedMethod(); 
    this.key = null; 
    } 
} 

class RestrictedAccessClass{ 
    public void restrictedMethod(){ 
    if(allowedCallerInstance.getKey() != this){ 
     throw new NullPointerException("forbidden!"); 
    } 
    // do restricted stuff 
    } 
} 

私は)restrictedMethod(へのマルチスレッドの同時アクセスを防止するために改善することができると思います。
また、キーはAllowedCaller以外の別のクラスにある可能性があります(RestrictedAccessClassはAllowedClassについて知る必要はありません)。そのようなコントロールは集中することができるので、単一のキーではなく、同時に。

関連する問題