oop - 域模型中的继承与枚举属性

标签 oop inheritance enums domain-driven-design domain-model

我在工作中讨论了“域模型中的继承使开发人员的生活变得复杂”。我是一个面向对象的程序员,所以我开始寻找在域模型中继承会减轻开发人员生活的论点,而不是到处都有开关。

我想看到的是:

class Animal {

}

class Cat : Animal {

}

class Dog : Animal {

}

另一位同事说的是:
public enum AnimalType {
    Unknown,
    Cat,
    Dog
}

public class Animal {

    public AnimalType Type { get; set; }

}

我如何说服他(链接是 WELCOME )在这种情况下,类层次结构比拥有枚举属性更好?

谢谢!

最佳答案

以下是我的推理方式:

仅当角色/类型永远不会改变时才使用继承。
例如

将继承用于以下内容:

消防员 <- 员工 <- 人错了。

一旦消防员弗雷迪更换工作或失业,您就必须杀死他并重新创建一个新类型的新对象,并附上所有旧关系。

因此,上述问题的天真解决方案是为 person 类提供 JobTitle 枚举属性。
这在某些情况下就足够了,例如如果您不需要与角色/类型相关的非常复杂的行为。

更正确的方法是给 person 类一个角色列表。
每个角色代表例如具有时间跨度的就业。

例如

freddy.Roles.Add(new Employement( employmentDate, jobTitle ));

或者如果这太过分了:
freddy.CurrentEmployment = new Employement( employmentDate, jobTitle );

这样,Freddy 就可以成为一名开发人员,而不必先杀了他。

但是,如果您应该为职位使用枚举或类型层次结构,我所有的漫谈仍然没有回答。

在纯内存 OO 中,我会说在这里对职位使用继承更正确。

但是如果你在做 O/R 映射,如果映射器试图将每个子类型映射到一个新表,你可能会在幕后得到一个有点过于复杂的数据模型。
因此,在这种情况下,如果没有与类型相关的真实/复杂行为,我通常会采用枚举方法。
我可以接受“if type == JobTitles.Fireman ...”,如果使用受到限制并且它使事情变得更容易或更不复杂。

例如.NET Entity Framework 4 设计器只能将每个子类型映射到新表。当你查询你的数据库而没有任何真正的好处时,你可能会得到一个丑陋的模型或大量的连接。

但是,如果类型/角色是静态的,我确实使用继承。
例如对于产品。

您可能有 CD <- 产品和书籍 <- 产品。
继承在这里获胜,因为在这种情况下,您很可能具有与类型相关联的不同状态。
CD 可能有多个轨道属性,而一本书可能有多个页面属性。

简而言之,这取决于;-)

此外,在一天结束时,您很可能会以任何一种方式结束很多 switch 语句。
假设你想编辑一个 "Product",即使你使用继承,你可能会有这样的代码:

如果(产品是书)
Response.Redicted("~/EditBook.aspx?id"+ product.id);

因为在实体类中对编辑簿 url 进行编码会很丑陋,因为它会迫使您的业务实体了解您的站点结构等。

关于oop - 域模型中的继承与枚举属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4254182/

相关文章:

java - 如何静态检测丢失的@Override 注释?

java - 为什么一个接口(interface)不能实现另一个接口(interface)?

c# - 部分类/部分方法与基类/继承类

java - 如何为 ButtonGroup setSelected(其中所有 JRadioButton 都是在循环中创建的)?

c# - 为什么 "Not all code paths return a value"带有 switch 语句和枚举?

c# - 单击后更改按钮文本,然后再次单击后将其更改回

c++ - 指针模板数组 C++?

java - 将枚举中的所有名称作为 String[]

Java - 具有泛型类型参数的重写方法,并在调用它时对其进行类型转换

javascript - 在javascript es6中,如何在不使用类名的情况下调用构造函数方法?