我有一个包含 3 个表的数据库。 人
、球员
和教练
。 person
表包含 player
和 coach
的共同点,例如 firstName
、lastName
和 电子邮件
。然后,player
和 coach
表有一个返回到带有 personId
字段的 person
表的链接。每个访问该站点的人都有一个 person
条目。此外,某些用户可能还有 player
或 coach
条目。数据库以这种方式设置以保持规范化。
在我的代码中,我有一个person
、player
和coach
类。 player
和 coach
继承自 person
。下面是 person
和 player
类的截断版本。
class person{
private $firstName;
private $lastName;
public function __construct($firstName, $lastName){
$this->firstName = $firstName;
$this->lastName = $lastName;
}
}
class player extends person{
private $position;
private $jersey;
public function __construct($firstName, $lastName, $position, $jersey){
parent::__construct($firstName, $lastName);
$this->position = $position;
$this->jersey = $jersey;
}
}
提醒一下,我是 OOP 的新手,所以如果有什么我不知道的地方,请多多包涵。
(附带问题,上面的类都考虑了什么,Views?)
现在为了填充这些,我使用我理解的模型类(对吗?)。
class personModel{
public function getPerson($personId){
$sql = "SELECT * FROM `person` WHERE `personId` = '$personId'";
//skipping some sql stuff in here
return new person($sql['firstName'], $sql['lastName']);
}
}
但现在我的核心问题是如何实现 playerModel
?
class playerModel{
public function getPlayer($playerId){
//would I do a join SQL here?
//or would I call personModel::getPerson()
//or do both these options couple the two classes too tightly?
}
}
某种类型的 factory
类是另一种选择吗?如果是这样,那将如何完成?
我需要能够构造 person
、player
和 coach
对象,因为我的用户将属于所有这些类别.
非常感谢任何反馈,如果我需要澄清任何事情,我会经常回来查看。
最佳答案
我将从你的附带问题开始,因为术语是谈论 OOP 时第一个重要的部分:
- 您的类
person
、player
和coach
是模型。该模型的目的是将现实的重要部分转换到程序中,以便您(作为程序员)可以直观地使用有关业务领域的术语。 - View 不是标准的 OOP 术语,有时它是数据库内部的抽象,因此您可以使用 View 来处理一个或多个表,而不是直接使用表。有时它是模型的 GUI。
您的类 personModel
和 playerModel
与其说是模型,不如说是持久性 Controller ,或者如您所说,是工厂。如果您想学习 OOP 以及从关系数据库加载/保存模型的可能性,您可以轻松编写自己的代码,类似于 SQL 代码。类 DBManagement
可以通过 loadPersons()
等操作实现这一目的。该操作查询数据库,构建所有人员对象并返回它们。同样,保存可以与 updatePerson(person $person)
一起使用。
稍后您可以使用某种 ORM(对象关系映射器)持久性框架(我自己没有使用 PHP 的经验,但是 doctrine ORM 可能很有趣。在 Java 或 .Net 中经常使用 Hibernate)。
此外,我建议您以另一种方式设计您的模型。事实上,让 player
和 coach
继承自 person
的想法是正确的,这样您就可以共享公共(public)属性,例如 firstName
。但在这种情况下,该模型不够灵活,无法让您在上一句话中提到,某些用户属于所有类别。一个特例是一个人,实际上是一个球员,将成为一名教练。例如,如果 Martin 是一名球员但现在要成为一名教练,则您必须将一个 Martin 对象换成另一个。这意味着马丁和以前不是同一个人,只是因为他成为了一名教练,这听起来很奇怪,不是吗?
相反,您可以定义每个用户始终是一个人
。有些用户是教练
,有些是球员
,有些两者都是,有些则不是。但始终是一个人
。
一些用于说明的伪代码:
class Person {
string firstName;
string lastName;
List<PersonRole> roles;
}
abstract class PersonRole {}
class Coach extends PersonRole {}
class Player extends PersonRole {
int position;
string jersey;
}
这样每个用户(=Person)都可以没有任何角色。如果用户具有角色,则可以在该角色对象中保存该用户的特定角色属性。当然,一个人的角色列表会随着时间的推移而改变,这取决于这个人实际拥有的角色。
一个巧妙的副作用是该模型更符合您的数据库架构,因此您应该可以毫不费力地将关系数据库架构转换为模型实例,反之亦然。
关于PHP mySQL 从子类构造父数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14094902/