2012-07-04 66 views
4

所以,這裏有一個例子。我在包HTTP中有一個庫。我定義了庫中的子部分,例如包HTTP.TCPProtocol。現在我想使用HTTP包中的TCPProtocol,這意味着我必須公開TCPProtocol功能。同時,此功能不應導出到庫的用戶。有沒有辦法將Java函數導出到庫中的其他包,但不是庫的用戶?

我如何做到這一點?我不想將整個庫整合到一個包中,因爲我覺得單獨的子包在eclipse中確實使代碼更加結構化和導航更容易。但瀏覽一下,我找不到在我的項目中公開函數的方法,但不能將它們導出到我的項目之外。

編輯:鑑於我能夠拿出一個更好的例子,我正在更新OP。

+0

也許看一看[OSGi包(http://en.wikipedia.org/wiki/OSGi#Bundles)。 –

+0

謝謝,它確實看起來像一個解決方案,但OSGi似乎有點沉重,因爲僅僅向共享庫發佈共享庫.jar。 :) – cib

回答

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(); 
    } 

} 
1

沒有看到你的依賴關係,社區可以給你的唯一真正的建議是重構你的代碼。如果你的網絡包中的某些東西需要了解你的遊戲引擎,那麼看起來你有一個漏洞抽象。很難說沒有看到你的代碼。

+0

抽象是漏洞少,我更習慣於能夠抽象化我的抽象。我的意思是,給你一個非常簡單的例子。如果我想編寫一個HTTP庫,但不允許我的庫的用戶發送任何類型的TCP消息,該怎麼辦?從概念分離的角度來看,有一個單獨的TCP軟件包是有意義的,但即使我不想讓它們成爲圖書館用戶,也會立即迫使我使得(功能良好)抽象的TCP功能可見。 – cib

2

一個簡單的方法是將您的'實用工具'方法列入白名單,以便它們僅接受某種類型的調用者實例。

package gameengine; 

interface Whitelisted {} // marker 

然後你的方法:

public void myMethod(Whitelisted caller, String arg) 

以及調用:

+0

這是一個有趣的方法。但gameengine.network如何控制白名單,儘管如此?界面不需要公開嗎? :) – cib

+0

的確如此。我不想擁有一個可能想調用它的每個可能類型的調用者的myMethod,但這是我現在唯一可以考慮的其他方法。 –

+0

此外,這還假定白名單的類不能實例化(就像單例)。 –

相關問題