设计模式-建造者模式

0x00 建造者模式定义
Separate the construction of a complex object from its representation so that the same
construction process can create different representations.
(将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。)

优点
封装性, 客户端不需要知道产品内部的细节.
建造者独立,容易扩展.
便于控制细节风险, 由于具体的建造者都是独立的,因此对建造过程中的逐步细化,不会影响到其他模块.

使用场景
相同的方法, 不用的执行顺序, 产生不同的事件结果时,可以采用建造者模式.
多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同的,则可以使用该模式.
产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效果,这个时候使用建造者模式非常合适.

注意
建造者模式关注的是零件类型和装饰工艺(顺序), 这个是它与工厂模式最大不同的地方。

PHP 实例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
abstract class AbstractQueryBuilder {
abstract function getQuery();
}

abstract class AbstractQueryDirector {
abstract function __construct(AbstractQueryBuilder $builder);
abstract function buildQuery();
abstract function getQuery();
}

class Model {
private $sql = NULL;
private $sql_table = NULL;
private $sql_where = NULL;
private $sql_limit = NULL;

function __construct() {
}

function querySql() {
    return $this->sql;
}

function table($table) {
    $this->sql_table  = $table;
}

function where($where) {
    $this->sql_where = $where;
}

function limit ($limit) {
    $this->sql_limit = $limit;
}

function splicingQuery () {
    $this->sql = 'SELECT * FROM ';
    $this->sql .= $this->sql_table;
    $this->sql .= ' WHERE ' . $this->sql_where;
    $this->sql .= ' LIMIT ' . $this->sql_limit;
}

}

class BaseQueryBuilder extends AbstractQueryBuilder {
private $query = NULL;
function __construct() {
$this->query = new Model();
}

function table($table) {
    $this->query->table($table);
}

function where($where) {
    $this->query->where($where);
}

function limit($limit) {
    $this->query->limit($limit);
}

function splicingQuery() {
    $this->query->splicingQuery();
}

function getQuery() {
    return $this->query;
}

}

class UserQueryDirector extends AbstractQueryDirector {
private $builder = NULL;
public function __construct(AbstractQueryBuilder $builder_sql) {
$this->builder = $builder_sql;
}

public function buildQuery() {
    $this->builder->table('User');
    $this->builder->where('id < 10');
    $this->builder->limit('100');
    $this->builder->splicingQuery();
}

public function getQuery() {
    return $this->builder->getQuery();
}

}

$queryBuilder = new BaseQueryBuilder();
$userDirector = new UserQueryDirector($queryBuilder);
$userDirector->buildQuery();
$userSql = $userDirector->getQuery();

var_dump($userSql->querySql());

// string(42) “SELECT * FROM User WHERE id < 10 LIMIT 100”

0x01 小结
各个设计模式之间有相似的地方. 比如封装性。