PHP 設計模式之流介面模式

echo_dump發表於2020-06-24

流介面模式 Fluent Interface

  1. 屬於結構型的設計模式

  2. 定義: 用來編寫易於閱讀的程式碼,就像自然語言一樣。

  3. 鄙人之見,流介面模式就是可以瀑布式(鏈式呼叫)介面來轉發一系列物件方法呼叫的上下文,這個上下文通常指

3.1 透過被調方法的返回值定義
3.2 自引用,新的上下文等於老的上下文
3.3 返回一個空的上下文來終止

  1. 最常見的就是各種php框架裡封裝的查詢sql的語句,透過流式介面模式,把sql語句封裝,然後供客戶端方便明瞭的呼叫

  2. 舉例:

namespace Fluent;

interface BuildInterface
{
    public function get();

    public function first();

    public function limit(int $number = 1):self;

    public function offset(int $number):self;

    public function table(string $table, string $alias = ''):self;

    public function where(array $wheres):self;

    public function select(array $fields = ["*"]):self;

    public function orderBy(string $orderName, string $sortType = 'asc'):self;

    public function groupBy(string $groupName):self;
}

class SqlBuild implements BuildInterface
{

    private $sql;

    private $table;

    private $select;

    private $where;

    private $limit = 1;

    private $order;

    private $group;

    public function __construct()
    {
        $this->sql = sprintf("select ");
    }

    public function get()
    {
        // TODO: Implement get() method.
        return $this->sql . $this->select . $this->table . $this->where . $this->order;
    }

    public function first()
    {
        // TODO: Implement first() method.
        return $this->sql . $this->select . $this->table . $this->where . $this->order . ' limit ' . $this->limit;
    }

    public function limit(int $number = 1): BuildInterface
    {
        // TODO: Implement limit() method.
        $this->limit = $number;

        return $this;
    }

    public function offset(int $number): BuildInterface
    {
        // TODO: Implement offset() method.
    }

    public function table(string $table, string $alias = ''): BuildInterface
    {
        // TODO: Implement table() method.
        $this->table = sprintf(" `%s` ", $table);

        !empty($alias) && $this->table .= sprintf("as %s", $alias);

        return $this;
    }

    public function where(array $wheres): BuildInterface
    {
        // TODO: Implement where() method.
        $tempWhere = '';
        static $level = 0;
        foreach ($wheres as $where => $item) {
            if (is_int($item)) {
                if ($level == 0) {
                    $tempWhere .= sprintf("`%s` = %d", $where, $item);
                } else {
                    $tempWhere .= sprintf(" and `%s` = %d", $where, $item);
                }
            } elseif (is_string($item)) {
                if ($level == 0) {
                    $tempWhere .= sprintf("`%s` = '%s'", $where, $item);
                } else {
                    $tempWhere .= sprintf(" and `%s` = '%s'", $where, $item);
                }
            } else {
                if ($level == 0) {
                    $tempWhere .= sprintf("%s = '%s'", $where, $item);
                } else {
                    $tempWhere .= sprintf(" and %s = '%s'", $where, $item);
                }
            }
            $level++;
        }

        $this->where = sprintf("where %s", $tempWhere);

        return $this;
    }

    public function select(array $fields = ["*"]): BuildInterface
    {
        // TODO: Implement select() method.
        $select = implode("`, `", $fields);
        $select = rtrim($select, ',');
        $select = '`' . $select . '`';
        $this->select = sprintf("%s from ", $select);

        return $this;
    }

    public function orderBy(string $orderName, string $sortType = 'asc'): BuildInterface
    {
        // TODO: Implement orderBy() method.
        $this->order = sprintf(" order by `%s` %s", $orderName, $sortType);

        return $this;
    }

    public function groupBy(string $groupName): BuildInterface
    {
        // TODO: Implement groupBy() method.
        $this->group = sprintf(" group by %s", $groupName);

        return $this;
    }
}
  1. 測試
class Client
{
    public function __construct()
    {
        $sqlBuild = new SqlBuild();

        $sqlQuery = $sqlBuild->table('users')
            ->select(['id', 'name'])
            ->where(['id' => 10, 'name' => 'liyi', 'email' => '123@test.com'])
            ->orderBy('id', 'desc')
            ->first();

        echo $sqlQuery;
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結
LIYi ---- github地址

相關文章