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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
class ShopProduct {
    private $title;
    private $producerMainName;
    private $producerFirstName;
    protected $price;
    private $discount = 0; 
    private $id = 0;
     
    public function __construct(   $title$firstName
                            $mainName$price ) { 
        $this->title             = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName  = $mainName;
        $this->price             = $price;
    }
 
    public function setID( $id ) {
        $this->id = $id;
    }
 
    public function getProducerFirstName() {
        return $this->producerFirstName;
    }
 
    public function getProducerMainName() {
        return $this->producerMainName;
    }
 
    public function setDiscount( $num ) {
        $this->discount=$num;
    }
 
    public function getDiscount() {
        return $this->discount;
    }
     
    public function getTitle() {
        return $this->title;
    }
 
    public function getPrice() {
        return ($this->price - $this->discount);
    }
 
    public function getProducer() {
        return "{$this->producerFirstName}".
               " {$this->producerMainName}";
    }
 
    function getSummaryLine() {
        $base  "$this->title ( $this->producerMainName, ";
        $base .= "$this->producerFirstName )"
        return $base;
    }
 
    public static function getInstance( $id, PDO $pdo ) {
        $query "select * from products where id='$id'";
        $stmt $pdo->prepare("select * from products where id=?");
        $result $stmt->execute( array$id ) );
        $row $stmt->fetch( );
        if empty$row ) ) { return null; }
 
        if $row['type'] == "book" ) {
            $product new BookProduct( 
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'], $row['numpages'] ); 
        else if $row['type'] == "cd" ) {
            $product new CdProduct(
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'], $row['playlength'] ); 
        else {
            $product new ShopProduct(     
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'] ); 
        }
        $product->setId(            $row['id'] );
        $product->setDiscount(      $row['discount'] );
        return $product;
    }
}
 
class CdProduct extends ShopProduct {
    private $playLength = 0;
 
    public function __construct(   $title$firstName
                            $mainName$price$playLength ) { 
        parent::__construct(    $title$firstName
                                $mainName$price );
        $this->playLength = $playLength;
    }
 
    public function getPlayLength() {
        return $this->playLength;
    }
 
    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": playing time - $this->playLength";
        return $base;
    }
  
}
 
class BookProduct extends ShopProduct {
    private $numPages = 0;
 
    public function __construct(   $title$firstName
                            $mainName$price$numPages ) { 
        parent::__construct(    $title$firstName
                                $mainName$price );
        $this->numPages = $numPages;
    }
 
    public function getNumberOfPages() {
        return $this->numPages;
    }
    
    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": page count - $this->numPages";
        return $base;
    }
 
    public function getPrice() {
        return $this->price;
    }
}
 
require_once("generate_product_pdo.php");
$pdo = getPDO();
$obj = ShopProduct::getInstance( 1, $pdo );
print_r( $obj );
$obj = ShopProduct::getInstance( 2, $pdo );
print_r( $obj );
$obj = ShopProduct::getInstance( 3, $pdo );
print_r( $obj );
?>

这个方法再类中会比在对象中更有用。

我们可以轻松地将原始数据转换为一个对象,而不需要一开始就使用ShopProduct对象。

这个方法并没有使用任何实例属性或方法吗所以没有理由不把他定义为static。

只要有一个有效的PDO对象,我们就可以再程序的任何地方(应该要先把class include进来吧)调用这个方法:

1
2
3
4
$dsn "xxxxxxxxxxxxx";
$pdo new PDO($dns,null,null);
$pdo->getAttribute(xxxxxxxxxxxxxxxxx, xxxxxxxxxxxxx);
$bjg = ShopProduct::getInstance(1, $pdo);

如果这个类的父类已经有了数据库连接的实例应该不用传这个pdo实例就可以直接返回数据了。