哪种类设计更好,为什么?
public class User
{
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee : User
{
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member : User
{
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
OR
public class User
{
public String UserId;
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee
{
public User UserInfo;
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member
{
public User UserInfo;
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
答案 0 :(得分:54)
通过认识到继承模拟“IS-A”关系,而成员模型为“HAS-A”关系,可以简单回答这个问题。
哪一个是正确的?这是你的答案。
答案 1 :(得分:18)
我不喜欢任何一个。当某人既是会员又是员工时会发生什么?
答案 2 :(得分:15)
问自己以下几点:
总的来说,在代码复杂性和所需效率的限制下,努力模拟程序模拟的现实。
答案 3 :(得分:12)
我认为组合总是比继承更好(通常)。如果员工和会员真的是用户,并且他们互相排斥,那么第一个设计就更好了。考虑您需要访问Employee的UserName的场景。使用第二种设计:
myEmployee.UserInfo.UserName
这很糟糕(Demeter法则),所以你要重构:
myEmployee.UserName
需要Employee上的一个小方法委托给User对象。第一种设计避免了所有这些。
答案 4 :(得分:12)
不错的问题,虽然为了避免分散正确和错误,我会考虑询问每种方法的优缺点 - 我认为这就是你的意思是好还是坏,为什么。无论如何......
优点:
缺点:
优点:
缺点:
这些列表+提到的问题Jon Limjap将帮助您做出决定并开始使用 - 然后您就可以找到正确的答案应该是什么; - )
答案 5 :(得分:7)
您还可以将员工视为用户(人员)的角色。用户的角色可以及时更改(用户可能失业)或用户可以同时拥有多个角色。
当真实时,继承会更好。""关系,例如Apple - Fruit。但要非常小心:圆圈 - 椭圆不是真的"是一个"关系,因为cirlce的自由度较低"比椭圆(圆是椭圆的状态) - 参见:Circle Ellipse problem。
答案 6 :(得分:5)
真正的问题是:
这些实体可以是三个完全不相关的实体,这将决定您的第一个或第二个设计是否有效,或者是否有其他完全不同的设计。
答案 7 :(得分:4)
两者都不好。太多可变的状态。您不应该构造处于无效或部分初始化状态的类的实例。
那就是说,第二个更好,因为它有利于构成而不是继承。
答案 8 :(得分:3)
陈述您的要求/规格可能有助于达到“最佳设计” 你的问题目前也是“主题 - 读者解释”。
答案 9 :(得分:2)
这是你应该考虑的一个场景:
如果同一用户既可以是员工又可以是会员,则最好使用组合(第2个示例)。为什么?因为对于表示同一用户的两个实例(Employee和Member),如果用户数据发生更改,则不必在两个位置更新它。只有User实例包含所有用户信息,并且只有它必须更新。由于Employee和Member类都包含相同的User实例,因此它们将自动包含更新的信息。
答案 10 :(得分:0)
还有三个选项:
让User
类包含员工和成员的补充信息,未使用的字段为空(特定ID
的{{1}}表示用户是否为员工,成员,两者或其他)。
有一个User
类,其中包含对User
的引用,其中ISupplementalInfo
由ISupplementalInfo
,ISupplementalEmployeeInfo
继承,等等。适用于所有用户的,可以使用ISupplementalMemberInfo
类对象,具有User
引用的代码可以访问用户的补充信息,但这种方法可以避免更改User
如果将来需要不同的补充信息组合。
如上所述,但User
类包含某种User
的集合。该方法具有便于向用户运行属性的运行时间的优点(例如,因为雇用了ISupplementalInfo
)。使用前面的方法时,必须为不同的属性组合定义不同的类;将“会员”变成“会员+客户”需要不同的代码才能将“员工”变成“员工+客户”。后一种方法的缺点是它会使得更难以防止冗余或不一致的属性(使用类似Member
的东西来保存补充信息可能有效,但看起来有点“笨重”)。
我倾向于支持第二种方法,因为它允许未来的扩展比直接继承更好。使用一组对象而不是单个对象可能会有点麻烦,但这种方法可能比其他方法更好地处理不断变化的需求。