2017-07-28 44 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