2017-07-28 78 views
1

我搜索了很多關於我的問題的答案,並發現了幾個選項,想知道這是最佳實踐。外部訪問內部私人類字段的Java最佳實踐

使用案例: 所以我有一個單一類AccontManager,它有一個只與它有關的內部類,這是一個User類。現在

public class AccountManger { 

private static final AccountManger ourInstance = new AccountManger(); 
private User user; 

public static AccountManger getInstance() 
{ 
    return ourInstance; 
} 

private AccountManger(){} 

public User getUser(){ 
    return this.user; 
} 

private class User{ 
    private String id; 

    private User (String id){ 
     this.id = id; 
    } 
} 
} 

的情況是,User領域具有訪問到外面包類,但用戶類是獨一無二隻此singleton類,因此內部類是私有的。

理想情況下,在內部類中創建公共getter方法以獲取用戶字段將是最好的,但由於內部類是私有的,這是不可能的。

可能的做法:

  1. 實踐:創建外AccountManager類各自的getter方法爲User領域。

    缺點:用戶字段與User相關,因此外部類不應該在其字段中使用getter方法。

    代碼示例

    public class AccountManger { 
    
        private static final AccountManger ourInstance = new AccountManger(); 
        private User user; 
    
        public static AccountManger getInstance() 
        { 
         return ourInstance; 
        } 
    
        private AccountManger(){} 
    
        public User getUser(){ 
         return this.user; 
        } 
    
        public String getUserId() // <-- get User id 
        { 
         return user.id; 
        } 
    
        private class User{ 
         private String id; 
    
         private User (String id){ 
          this.id = id; 
        } 
    } 
    } 
    
  2. 實踐:在User修飾符更改爲public,但保留構造私有的,所以它不能被實例化。

    缺點:內User類會隨着AccountManager單個類,它不應該是的成員可見。

    代碼示例

    public class AccountManager { 
    
        private static final AccountManger ourInstance = new AccountManager(); 
        private User user; 
    
        public static AccountManager getInstance() 
        { 
         return ourInstance; 
        } 
    
        private AccountManger(){} 
    
        public User getUser(){ 
         return this.user; 
        } 
    
        public String getUserId() // <-- get User id 
        { 
         return user.id; 
        } 
    
        private class User{ 
         private String id; 
    
         private User (String id){ 
          this.id = id; 
         } 
        } 
        } 
    
  3. 實踐

    • 創建一個公共接口,例如,IUser
    • 使內部類User實現該接口
    • 添加到外部類,在這種情況下AccountManager的吸氣劑的方法向User實例

    缺點:需要以從User獲得數據所用的接口。

    代碼示例

    public class AccountManager { 
    
    private static final AccountManager ourInstance = new AccountManager(); 
    private User user; 
    
    public interface IUser{ 
        String getName(); 
    } 
    
    private AccountManager(){} 
    
    public static AccountManager getInstance(){ 
        return ourInstance; 
    } 
    
    public User getUser(){ 
        return this.user; 
    } 
    
    private class User implements IUser{ 
        private String id; 
    
        private User(String id){ 
         this.id = id; 
        } 
    
        @Override 
        public String getName() { // <-- get user id 
         return id; 
        } 
    } 
    } 
    


    所以,你有什麼感想?
    列出的任何一個選項?
    還有其他的一些方法嗎?

謝謝您的輸入

回答

2

我要說的是,User類必須private,那AccountManager應實施getterssetters到它的屬性。

你不會知道什麼是User,因爲AccountManager會告訴你你可以什麼知道。作爲一個加號,你可以服從Law of Demeter,這總是好事。

IMO,應該使用內部類作爲一種方法來使外部類中的代碼變得更清潔,並且它們不應該在其他地方使用。

但我想在User私人的構造函數總比沒有好。

0

我看到三個替代方法:

  • 讓用戶類單機和公衆(和給它一個的AccountManager場,如果需要的話)。然後用戶成爲您的公共API的一部分 - 可能不是你想要的。

  • 在AccountManager類中,爲公共相關的用戶屬性創建getters和setter。這使用戶實體成爲客戶經理的一個不可見部分。 (比喻:如果你談論你的汽車的馬力,你隱藏的事實是它不是汽車本身的屬性,而是它的引擎的屬性,這很好)。

  • 如果您希望用戶的概念成爲API的一部分,但仍然希望保持內部User類爲private,請使用公用相關方法創建IUser接口並讓User實現IUser。然後,您可以在AccountManager中公開public IUser getUser()方法,而外部世界只能看到在界面中聲明的功能。

0

眼見爲AccountManager(你在你的代碼示例拼錯的「經理人」)是一個單獨的類,它沒有真正有效的區別,但你說你自己,「用戶級的獨特之處在於這單身人士「,所以User類的目的可能會更好地代表,如果你使它static

無論如何,在您的原始代碼示例中,您包含一個方法public User getUser()。由於類Userprivate,我並沒有真正看到這一點,因爲在類AccountManager之外,任何對User對象的引用都是無用的,因爲您將永遠無法訪問其任何成員或聲明一個User變量,以便將由此獲得的User參考賦值給哪個變量。唯一可能的使用情況下,我可以設想是,如果AccountManager聲明的方法接受一個User參數(比的User較高或任何訪問修飾符)一public。但即使是這樣的話,我會質疑這樣的設計是否是你想要真的是。

因此,您可能想要考慮是否真的需要方法public User getUser(),只要User停留private。這已經把我們引向你原來的問題。我認爲你首先提出的解決方案更好。這對我來說,似乎正是爲什麼一個超被允許訪問一個子類的'私人」成員的原因。引用自this answer在計算器上:

內部類(爲了訪問控制的目的)被認爲是包含類的一部分。這意味着完全訪問所有私人。

所以,如果你想User爲的AccountManager一部分,那麼你也不必感到內疚從AccountManager內,但來自外部User訪問其private領域,因爲很明顯,爪哇的設計師也認爲那樣。

最後,如果你不打算一個User存續期間更改的字段id,你可以做idfinal