1

所以我正在编写DataBase类,它将成为 和 之间的封装PHP ControllerMySQL View

interface iDataBase {
    public function drug($action, $drug);
    public function company($action, $company);
    public function activeIngredient($action, $activeIngredient);
}

一开始我想把所有的setter和getter分开,比如getAllDrugs()、updateDrug()、removeDrug()、getForUpdate()、getDrug()等等,但后来我意识到我用太多的函数污染了数据库接口,加上这是一个非常小规模的版本,我正在考虑添加更多的类和更多的功能。所以,我没有使用很多功能,而是选择了 3.$action来确定用户想要对某个类做什么样的事情。所以,目前,可能的行动是:"add", "getAll", "getForUpdate", "update", "remove"

但是这些被屏蔽的函数$action有不同的事情要做,所以它们的返回结果不同,第二个参数也可以不同。

我的解决方案是一个好习惯吗?相信很多人都遇到过同样的问题,请问你们是怎么解决的呢?有没有可能的问题?

PSDrug, Company, ActiveIngredient都是类

4

4 回答 4

3

一个函数应该有明确定义的、狭窄的职责和明确定义的、极简的返回类型。如果你开始创建“上帝函数”,它会根据你传递的参数来做所有事情和厨房水槽,那么你将严重进入难以维护的意大利面条代码领域。您不想要一个执行 A 并在传递 X 时返回 B 的函数,但执行 C 并在传递 Y 时返回 D 等...

当你看到类似的模式出现时,随着时间的推移开始具体和概括是个好主意。因此,创建您实际需要的方法:

public function findUserById($id)
public function findUserByEmail($email)
public function updateCompanyName($id, $newName)

如果您发现在这些函数之间共享代码,请统一后台代码以使其保持 DRY:

public function findUserById($id) {
    return $this->find('SELECT * FROM user WHERE id = ?', $id);
}

public function findUserByEmail($email) {
    return $this->find('SELECT * FROM user WHERE email = ?', $email);
}

protected function find($query, $arg) {
    ...
}

不要以相反的方式开始,认为你“只需要 X、Y 和 Z”,它们看起来足够相似,可以统一到一个方法中,然后发现 X、Y 和 Z 之间存在细微差异,并在你的代码中乱扔垃圾每个的特殊情况。这只会导致函数要么巨大要么太笼统,它们基本上自己什么都不做。

于 2012-10-24T11:33:33.077 回答
2

您可能正在寻找的东西称为TableDataGateway(重点是我的):

表数据网关包含用于访问 单个 或视图的所有 SQL:选择、插入、更新和删除。其他代码调用其方法进行与数据库的所有交互。

这意味着您将拥有一个通用数据库适配器,例如一个 PDO 对象。您将其注入到您的各种 TDG 中。然后,TDG 使用该适配器从数据库中 CRUD 数据。

例子

class CompanyTableGateway
{
    private $dbAdapter;

    public function __construct(DBAdapter $dbAdapter)
    {
        $this->dbAdapter = $dbAdapter;
    }

    public function create($name, $street, $whatever)
    {
        $this->dbAdapter->exec( 'INSERT INTO companies …' );
    }

    public function findById($id) 
    {
        return $this->dbAdapter->exec(
            sprintf('SELECT * from companies where id = %d', $id)
        );
    }

    // more methods …
}

如果您有多个此类网关,则可以将通用 CRUD 逻辑抽象为一个抽象类,然后从中扩展具体的网关。

然后,您将使用TableModule或类似的其他对象来调用各个网关上的方法。

于 2012-10-24T12:10:34.467 回答
1

关于关注点分离与单一职责原则的永无止境的讨论。

尝试充分利用两者,并相应地为您的课程建模。

于 2012-10-24T11:32:20.050 回答
1

我建议你做一个全局数据库类,它控制数据库的基本输入/输出,然后将其扩展到每个表。

这方面的一个示例可能是用户表。你可以对这张桌子做的是

  1. 创造
  2. 更新
  3. 删除

然后,您将使用用户类扩展超级数据库类,该类将为您想要的每个函数提供 getter 和 setter,即:

class Users extends DatabaseClass {
    public function update ( $params )
    {
        // Make the code for an update, and let the SuperClass execute the code.
        ...
    }

    public function add ( $params )
    {
        ...
    }

    public function delete ( $params )
    {
        ...
    }
}

这将允许您稍后轻松地向用户表添加更多功能,并专门针对您正在使用的表/数据优化查询。

于 2012-10-24T11:40:17.420 回答