PHP面向对象编程:如何创建一个新类?

3

我有3个表:

users:
id
first_name
last_name

courses:
id
name

student_courses:
id
student_id
course_id
paid

用户跟踪用户,课程跟踪课程,student_courses是显示学生注册了哪些课程的表。 我目前有一个“用户”类和一个“课程”类。我的问题是:我应该创建一个StudentCourses类来处理student_courses表的交互吗?

例如:我需要创建一个函数,获取用户注册的所有课程,标记为已支付等。

最好的做法是:

$student = new User($userId); 
$student->getCourses();
$student->markCourseAsPaid($courseId);

或者

$student = new User($userId);
$studentCourses = new StudentCourses($studentId);
$studentCourses->markCourseAsPaid($courseId);

etc.

5个回答

4
如果你从对象的角度思考你的student_coursescourses表,你会发现student_courses是真正有趣的表,因为它包含了学生的个体对象。这些对象是你想要让你的Student对象连接到的对象。而在courses中,你现在只有课程的不变部分,例如它的名称和描述。因此,你的StudentCourse实例可以简单地聚合它。你只需要加载那个实例一次,然后在StudentCourse实例之间共享它。

Student hasMany Courses hasOne CourseDescription

对于 Cohesion,你的 markAsPaid 方法应该在需要最多信息才能完成的对象上。换句话说,它应该在 Course 上。但是,你可以在学生上添加一个payForCourse代理方法,然后调用适当的Course上的markAsPaid。你可能需要引入一个充当存储库Courses类。

我觉得我明白你的意思了。你会如何建议使用以下代码为学生注册课程:$student = new Student($studentId); $course = new Course($courseId); - execv

3
如果您将来要扩展该应用程序,我建议为StudentCourse创建一个单独的类。目前它除了关联属性(paid)外只有一个附加属性,但是当您需要添加另一个属性时,您仍然会创建这个类。

0

在这种情况下,看起来两种方法都可以。

通常,在MVC(模型-视图-控制器)范例中,您会将每个模型/表作为一个类(即学生、课程、用户等)。然后,在每个类中,您可能会有一个变量来关联它们。我不认为需要StudentCourses类,即使表结构显示了关系,也不应该需要另一个类。第一个示例对我来说更具面向对象的特性。再次强调,您可以采用任何一种方式,但我总是选择更多面向对象的代码。


0
我不会创建单独的类。我的方法是使用类似以下的内容:
$student = new User($userId);
$course = new Course($courseId);
$student->markCourseAsPaid($course);

由于student_courses表只是一个关系,所以不需要额外的类。额外的类会暗示它是一个实体,但它不是,它是一个关系。

我的代码与你的不同之处在于,我首先获取适当的Course实例,然后将该实例传递给用户。我认为仅传递课程ID很奇怪,因为那么User对象只接收一个没有任何意义的数字作为参数。我们可能没有课程的ID(主键),而是有一个次要键。那么这个方法就变得无用了,因为它期望PK,而不是某些SK。因为我选择先获取Course对象,所以我们没有这个问题,因为Course对象知道如何通过次要键检索正确的课程。

编辑:由于这是一个对象化的关系,使用额外的类可能有一些意义。但是,我会采用另一种方法:

$studentCourse = new StudentCourse($studentId, $courseId);
$studentCourse->markPaid();

由于学生ID和课程ID组成了表的次要键,因此它们都应在构造函数中指定。


放弃第二行和$student->markCourseAsPaid($courseId);不是更好的选择吗……为了这个命令没有必要加载课程信息(包括数据库查询),除非new Course($courseId);使用惰性加载(实际上与未创建它相同)。 - Rudu
@Rudu 是的,我正在努力解释这个问题 ;) 我确实希望ORM类足够聪明,直到实际请求之前不会加载任何值。 - Joost

0

我会创建一个第三个类别 course_student,它将依赖于你的数据库中的一张表格和一个视图view,原因是关注点分离。

你的视图用于所有选择操作,而表格用于插入、更新和删除操作。

你的视图将由两个表格(学生和课程)的所有相关字段组成(使用2个inner join),基于你的course_student表中的关联关系。

一行数据看起来像这样:

student_id, student_first_name, student_last_name, courses_id, courses_name, is_paid

如果您想获取所有正在学习某门课程的学生,您可以编写一个名为 getStudentsByCourse(courseId) 的方法。
如果您想获取特定学生正在学习的所有课程,您可以编写一个名为 getStudentCourses(studentId) 的方法。
如果您需要为一门课程(或多门课程)注册一组学生,您可以编写一个名为 setStudentsCourses(studentId, courseId) 的方法,并且两个参数都可以是整数或数组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接