哪个班级设计更好?

Ram*_*oni 30 oop class-design

哪种类设计更好,为什么?

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;
}
Run Code Online (Sandbox Code Playgroud)

要么

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;
}
Run Code Online (Sandbox Code Playgroud)

180*_*ION 53

通过认识到继承模型是"IS-A"关系,而成员模型是"HAS-A"关系,可以简单地回答这个问题.

  • 员工是用户
  • 员工拥有用户信息

哪一个是正确的?这是你的答案.

  • 对不起,虽然常见,但这是推理设计的可怕方法.人类语言模糊不清,编程语言无法承受. (37认同)
  • 我认为赞成聚合而不是继承是一种好习惯.我觉得这里有道理. (3认同)
  • 我会进一步扩展一点,说一个“员工”有一个“用户信息”*在这个域的上下文中*。如果你发现你的 `employee` 有一个 `postcode` 仅仅是因为 `user` 有,但是为了 `employee` 的商业目的,`postcode` 是不需要的(它是由合同强加给你的) `user`) 那么在这种情况下,组合可能比继承更合适。 (2认同)

Bra*_*son 18

我不喜欢任何一个.当某人既是会员又是员工时,会发生什么?

  • 如果每个类都实现了接口,并且从每个类中提取了公共属性,那么您可以让新类实现Member和Employee,包含公共类的正确实例以及您需要的额外实例和委托. (5认同)
  • 您的担心是有效的,它是第二个设计的论点,而不是反对两者的论点。 (3认同)

wil*_*ell 15

问自己以下几点:

  • 你要建模的员工IS用户?如果是这样,选择继承.
  • 你要建模的员工HAS用户信息?如果是这样,请使用合成.
  • 用户(信息)和员工之间是否涉及虚拟功能?如果是这样,请使用继承.
  • 员工可以有多个用户(信息)实例吗?如果是这样,请使用合成.
  • 将Employee对象分配给User(info)对象是否有意义?如果是这样,请使用继承.

通常,在代码复杂性和所需效率的约束下,努力模拟程序模拟的现实.


lia*_*nan 12

我认为组合总是比继承更好(通常).如果员工和会员真的是用户,并且他们互相排斥,那么第一个设计就更好了.考虑您需要访问Employee的UserName的场景.使用第二种设计,您将拥有:

myEmployee.UserInfo.UserName
Run Code Online (Sandbox Code Playgroud)

哪个是坏的(得墨忒耳法则),所以你会重构为:

myEmployee.UserName
Run Code Online (Sandbox Code Playgroud)

这需要Employee上的一个小方法委托给User对象.第一种设计避免了所有这些.


mac*_*llt 12

尼斯问题,虽然避免分心关于正确错误的我会考虑要求每种方法的利弊-我认为这是你的意思的是好还是坏,为什么.无论如何....

第一种方法又称继承

优点:

  • 允许多态行为.
  • 最初简单方便.

缺点:

  • 可能变得复杂或笨拙随着时间的推移,如果更多的行为和关系增加.

第二种方法又名作文

优点:

  • 很好地映射到关系表,结构化编程等非oop场景
  • 逐步扩展关系和行为是很简单的(如果不一定方便).

缺点:

  • 没有多态性因此使用相关信息和行为不太方便

这些列表+ Jon Limjap提到的问题将帮助您做出决定并开始 - 然后您可以找到正确答案应该是什么;-)


Mar*_*ski 7

您还可以将Employee视为用户(Person)的角色.用户的角色可以及时更改(用户可能失业)或用户可以同时拥有多个角色.

当存在真正的 "是一种"关系时,继承会好得多,例如Apple - Fruit.但要非常小心:圆圈 - 椭圆不是真正的"是一种"关系,因为cirlce比椭圆具有更少的"自由"(圆是椭圆状态) - 参见:圆椭圆问题.


Jon*_*jap 5

真正的问题是:

  • 用户背后的业务规则和用户故事是什么?
  • 员工背后的业务规则和用户故事是什么?
  • 会员背后的业务规则和用户故事是什么?

这些可以是三个完全不相关的实体,也可以不是,这将决定您的第一个或第二个设计是否有效,或者是否有其他完全不同的设计.