考虑到面向对象编程,数据库如何与对象一起发挥作用?例如,假设有一个 Student 类,具有姓名、编号、课程等属性
Student类也有行为(方法)。我认为合适的一些是
enrollForACourse()
、dropACourse()
、getStudentGPA()
、getAllStudentCourses()
等,或类似的东西。我不确定这些示例方法在凝聚力方面是否良好,但我会说是或也许。
我需要帮助的是数据库部分。因此,如果另一个不同的对象、用户或其他东西想要了解学生拥有的课程,则将使用 Student 类上的 getAllStudentCourses 方法。但不可避免的是,该信息存储在数据库中。
那么学生班级的
getAllStudentCourses()
方法会向数据库查询此信息吗?这是好的做法吗?这会遵循面向对象设计吗?等等同样适用于enrollForACourse()
。
如果 Student 类需要在方法中查询外部第 3 方服务怎么办?
你的问题不够明确和具体。但我指出一些注释来帮助你。与数据库进行通信建模有很多因素。
关于您的示例,其中一些会修改数据的状态,我们将其称为命令。命令可以在实体对象中具有相应的行为(实际上是方法)。
enrollForACourse
和 dropACourse()
是命令示例。但对于 getStudentGPA()
和 getAllStudentCourses()
,它们是其他对象(如存储库或(CQRS 中的查询处理程序))负责的查询。不要将您的查询放在实体本身中。查询很复杂,您的实体不应该被这些复杂性所污染。
GRASP 原则试图将职责分配给班级。所有这些技术、模式和实践都是为了遵守 GRASP。所以从面向对象的角度来看,你不应该在实体中放置额外的职责。
我不确定这些示例方法在凝聚力方面是否良好,但我会说是或也许。
我说这要看情况。其中一些很简单,可以通过导航属性(反映两个表之间关系的属性)来处理,就像您的所有四个示例一样,其中一些是复杂的查询或命令,涉及多个实体来处理(如
CanStudentEnrollInACourse()
)。在这些情况下,您应该使用存储库或查询处理程序。因为责任不在实体的范围内。
学生班级的 getAllStudentCourses() 方法会创建一个 查询数据库以获取此信息?这是好的做法吗?并且会 这遵循面向对象设计吗?等等与 enrollForACourse() 相同。
是的,只要实现不包含任何数据访问逻辑,例如导航属性(ORM 必须支持此功能),就可以接受。
如果 Student 类需要在方法中查询外部第 3 方服务怎么办?
为什么需要查询其他服务?是否可以将结果传递给实体?如果没有,您可以将第三方服务接口传递给您的实体。你的实体不会是纯粹的,但这样责任会更清晰。