我搜索了很多我的问题的答案并找到了几个选项,想知道你最好的做法是什么。
用例:
所以我有一个单例类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
字段必须访问外部包类,但用户类仅对此单例类是唯一的,因此内部类必须是私有的。
最理想的是,在内部类中创建公共getter方法以获取用户字段是最好的,但由于内部类是私有的,所以这是不可能的。
可能的做法:
练习:在AccountManager
字段的外部User
类中创建相应的getter方法。
缺点:用户字段与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;
}
}
}
练习:将User
修饰符更改为public
,但保持构造函数为私有,因此无法实例化。
缺点:内部User
类将作为AccountManager
单例类的成员显示,它不应该是。{1}}。
代码示例:
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;
}
}
}
实践:
IUser
User
实现该接口AccountManager
添加到User
实例的getter方法
缺点:需要使用接口才能从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;
}
}
}
那么你怎么看?
列出的任何一个选项?
还有其他方法吗?
感谢您的输入
答案 0 :(得分:3)
我会说User
类需要private
,并且AccountManager
应该对其属性getters
和setters
实施。< / p>
您不必知道什么是User
,因为AccountManager
会告诉您能够知道什么。作为一个加号,你可以服从Law of Demeter,这总是好事。
IMO,内部类应该用作使外层类中的代码更清晰的方法,并且它们不应该在其他地方使用。
但我想让User
私有的构造函数比什么都好。
答案 1 :(得分:0)
我看到了三种替代方法:
使User类成为独立和公共(如果需要,给它一个AccountManager字段)。然后用户成为您的公共API的一部分 - 可能不是您想要的。
在AccountManager类中,为公共相关的用户属性创建getter和setter。这使用户实体成为客户经理的不可见组件。 (打个比方:如果你谈论你的汽车的马力,你隐藏的事实是它不是汽车本身的属性,而是它的引擎,这很好)。
如果您希望用户的概念成为API的一部分,但仍希望保持内部User类的私有性,请使用公开相关的方法创建一个接口IUser,并让User实现IUser。然后,您可以在AccountManager中公开public IUser getUser()
方法,外部世界只能看到界面中声明的功能。
答案 2 :(得分:0)
看作AccountManager
(你拼写错误&#34;经理&#34;在你的代码示例中)是一个单身人士课程,它不会真正有效地发挥作用,但你自己也说过#&# 34;用户类仅对此单例类&#34;是唯一的,因此User
类的目的可能会更好地表示static
。< / p>
无论如何,在原始代码示例中,您添加了一个方法public User getUser()
。由于课程User
为private
,我真的没有注意到这一点,因为在课程AccountManager
之外,对User
对象的任何引用都将没用,因为你将永远无法访问其任何成员或声明一个User
变量,以便为其分配如此获得的User
引用。我可以设想的唯一可能的用例是AccountManager
声明public
(或任何高于User
的访问修饰符)接受User
参数的方法。但即便如此,我也会质疑这样的设计是否真的是你想要的。
所以你可能想要考虑一下你是否真的需要public User getUser()
方法,只要User
保留private
。这已经引导我们解决您的原始问题。我认为你提出的第一个解决方案更好。对我而言,这似乎正是允许超类访问“私人”的原因。子类的成员。引自stackoverflow上的this answer:
内部类(为了访问控制的目的)被认为是包含类的一部分。这意味着可以完全访问所有私人。
因此,如果您认为User
是AccountManager
的一部分,那么您不必为从private
内访问其AccountManager
字段感到内疚但是从外部User
,因为显然,Java的设计者也会这样想。
最后,如果您不想在id
存在期间更改字段User
,则可以id
final
。