你基本上有三种方法解决这个问题(其中之一,我会立即消除):
每班
- 一个表(这是一个我会消除);
- 具有可选列的记录类型;和
- 具有子表的记录类型取决于您加入的类型。
为了简单起见,我一般推荐(2)。所以一旦你有你的桌子:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
其中类型可以是'代理'或'铅'(例如)。或者,您可以使用一种字符类型代码。然后,您可以使用对象模型开始填充空白:
- 您有一个用户父类;
- 你有两个孩子班:领导和代理;
- 那些孩子有固定类型。
它应该很容易就位。
至于如何在一个语句中加载,我会使用某种工厂。假设这些准系统类:
class User {
private $name;
private $type;
protected __construct($query) {
$this->type = $query['type'];
$this->name = $query['name'];
}
...
}
class Agent {
private $agency;
public __construct($query) {
parent::constructor($query);
$this->agency = $query['agency'];
}
...
}
class Lead {
public __consruct($query) {
parent::constructor($query);
}
...
}
工厂看起来是这样的:
public function loadUserById($id) {
$id = mysql_real_escape_string($id); // just in case
$sql = "SELECT * FROM user WHERE id = $id";
$query = mysql_query($sql);
if (!query) {
die("Error executing $sql - " . mysql_error());
}
if ($query['type'] == 'AGENT') {
return new Agent($query);
} else if ($query['type'] == 'LEAD') {
return new Lead($query);
} else {
die("Unknown user type '$query[type]'");
}
}
或者,你可以有工厂方法上,比如说一个静态方法,用户类和/或使用查找类为类的查找表。
也许用这种查询结果资源污染类是最严格的OO意义上的可疑设计,但它很简单并且可行。
我真的很喜欢这个想法。但是最让我厌烦的是执行SQL来加载所有数据的地方......我不能把它放在User类中,因为根据类型,我需要不同的SQL。我不想把它全部放在Agent和Lead类中,因为大部分代码都是相同的,我想避免复制和粘贴...理想情况下,我希望User类能够加载共同的信息和Agent/Lead类来加载独特的信息......但是,我每次执行2个SQL语句,每次我实例化一个Agent或Lead,这是不希望的..... – SpaDusA 2009-07-27 15:44:39
你可以做到这一点在1个SQL语句中。告诉我,你用什么来加载一个特定的用户?你通过什么?一个ID?还有别的吗? – cletus 2009-07-27 15:52:45