一个初学者的问题:我不知道如何最好地组织这段代码,但基本上是这样的(伪代码时间):
if (form = submitted) {
submitted();
}
else {
printForm();
}
function submitted() {
process data from form;
if(errors = found) {
print warnings;
printForm();
} else {
submit to database;
}
}
function printForm() {
print form with databound elements;
}我使用下面的代码创建一个User对象,但是调用它两次似乎很奇怪--一次在submitted()中,一次在printForm()中,特别是因为如果发现错误,submitted()就会调用printForm()。
不幸的是,处理表单中的数据需要数据库访问(检查现有的电子邮件地址等),因此我必须在submitted()和printForm()中调用以下代码...
try {
$db = new Database();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$user = new User($db);
}
catch (PDOException $e) {
echo "<p>Error connecting to database: </p>".$e->getMessage();
} 但我的直觉告诉我这很糟糕。是吗?如果是这样,我应该如何修复它?
发布于 2012-02-24 02:22:49
使用dependency injection
function submitted(Database $db, User $user) {
// ...
}
function printForm(Database $db, User $user) {
// ...
}
try {
$db = new Database();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$user = new User($db);
}
catch (PDOException $e) {
echo "<p>Error connecting to database: </p>".$e->getMessage();
}
submitted($db, $user);
printForm($db, $user);当然,最好使用OOP,因为这样就不必将依赖注入到每个单独的函数中:
class Foo {
protected $db;
protected $user;
public function __construct(Database $db, User $user) {
$this->db = $db;
$this->user = $user;
}
public function submitted() {
// use $this->db and $this->user here
}
public function printForm() {
// use $this->db and $this->user here
}
}
try {
$db = new Database();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$user = new User($db);
$foo = new Foo($db, $user);
}
catch (PDOException $e) {
echo "<p>Error connecting to database: </p>".$e->getMessage();
}
$foo->submitted();
$foo->printForm();发布于 2012-02-24 02:22:30
有几种方法可以让这一切变得更好。
一种方法是在函数调用之前初始化$user,并将其注入到每个函数中(依赖项注入)。
另一种方法是创建用户实例的单例(尽管我可以看到这会导致问题),并在函数中使用User::instance()之类的东西检索该实例。
在我看来,依赖注入更好,因为它使你的函数更容易测试。
现在,来看剩下的代码:
发布于 2012-02-24 02:24:12
尽管Singleton模式在某些情况下被认为是邪恶的,但在PHP中(每个请求都有一个单独的工作进程)和您的情况下,它似乎是实现您想要的东西的最简单方法。
这样,您就可以在任何页面上的任何脚本中使用发起请求的User实例,并且只需在每个项目的一个位置初始化$user对象(而不是像您希望的那样,在每个脚本中初始化一个)。
https://stackoverflow.com/questions/9418783
复制相似问题