管理员和用户的对象类型不同


Different type of object for admin and user

我正在构建一个intranet应用程序,我希望能够拥有两种不同类型的用户——普通用户和管理员用户。我正在努力找出做这件事的最佳方式。要么有一个对象用于管理类型的东西,然后有一个用于用户类型的东西。或者将两者合并为一个对象。但我一直陷入困境,不知道该怎么做,或者这是否是最好的方法。

假设我有以下情况:

1. query the db to get all tasks for all projects that are active.
    Admin Query
2. query the db to get all tasks for all projects that are due today and active.
    Admin Query
3. Query the db to get all tasks for a specific project that are active.
    Admin Query
    User Query
4. Query the db to get all tasks for a specific project that are active and due today.
    Admin Query
    User Query
5. Query the db to get all tasks for a specific project.
    Admin Query
    User Query
6. Query the db to get all tasks for a specific project, with different status specified.
    Admin Query
7. Any one of those queries has an optional parameter to either get the count or the data.

我启动了以下对象,但现在我有点纠结于该走哪条路线:

public function getTasks($status, $project, $type = "count", $duetoday = NULL)
    {
        try
        {
            if($duetoday != NULL){
                $today = date("Y-m-d"); 
                $stmt = $this->db->prepare("SELECT * FROM tasks WHERE status=:status
                                            AND $project=:project AND duedate BETWEEN :duedate 
                                            AND :duedate");
                $stmt->execute(array(':status'=>$status,':project'=>$project,':duedate'=>$today));
            }else{
                $stmt = $this->db->prepare("SELECT * FROM tasks WHERE status=:status
                                            AND $project=:project");
                $stmt->execute(array(':status'=>$status,':project'=>$project)); 
            }
            $tasks=$stmt->fetch(PDO::FETCH_ASSOC);
            if($stmt->rowCount() > 0)
            {
                if($type == "count"){
                    return $stmt->rowCount();
                }else{
                    return $tasks;
                }
            }else{
                return false;   
            }
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }
    }

我将从一些关于单一责任原则的词语开始。基本上,这意味着一个对象和它的行为应该有一个责任。在这里,我认为您的getTasks方法是将一些代码重构为更好的面向对象代码的好机会。

实际上它在做很多事情:

  • 生成sql
  • 执行查询
  • 控制程序的流程

生成sql的方法不必担心它的执行,执行它的方法也不必担心得到它。这作为一个副作用,也会减少单个方法中的嵌套。

有很多代码要写,我会让你这样做,但如果你创建了实现这些接口的类和使用它们的控制器,你应该能够完成这一任务,并编写更容易维护/重构的代码:

interface SqlGenerating {
    /**
     * @param array $params
     * @return string
     */
    public function makeSql(array $params);
    /**
     * @param array $params
     * @return array
     */
    public function makeValues(array $params);
}
interface DBAccessing {
    public function __construct('PDO $pdo);
    /**
     * @param string $sql
     * @param array $values
     * @return PDOStatement
     */
    public function getStmt($sql, array $values = []);
}
class Controller {
    public function __construct(SqlGenerating $sqlGenerator, DBAccessing $dbAccess) {
        // associate to private properties
    }
    public function getTasks($status, $project, $type = "count", $duetoday = null) {
        // this function will use the sqlGenerator and the dbAccess to query the db
        // this function knows to return the count or the actual rows
    }
}

如果您还没有,现在是学习函数中类型提示的好时机。这需要向函数传递一个对象(或数组),以确保函数的行为。此外,您会注意到,我在控制器中键入了接口。如果您需要一个不同的类来管理sql和数据库访问,这实际上是为了能够切换类。