设计模式之PHP实现(一)

设计模式之PHP实现(二)

原型模式

与工厂模式一样,都是用来创建对象的。

而原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象,这就免除了创建类时的重复操作。

原型模式适用于大对象的创建,创建一个大对象需要很大的开销,如果每次new就会占用很多资源,原型模式只是在内存中的拷贝。

基本类

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
<?php

require_once 'Loader.php';

class Canvas {

private $data;

function init($width = 20, $height = 10) {
$data = array();
for ($i = 0; $i < $height; $i++) {
for ($j = 0; $j < $width; $j++) {
$data[$i][$j] = '*';
}
}
$this->data = $data;
}

/**
* $x1 head第 x 行
* $x2 到第 x 行
* $y1 margin left 第几个
* $y2 到第几个
*/
function rect($x1, $x2, $y1, $y2) {
foreach ($this->data as $k1=>$line) { // $k1 是创建数组时的 $height 的值
if ($x1 > $k1 or $x2 < $k1) { // 当第1个参数大于$k1时,或者第2个参数小于$k1时.只会在指定的高度区间操作.
continue;
}
foreach ($line as $k2=>$char) { // $k2 是创建数组时 $width 的值
if ($y1 > $k2 or $y2 < $k2) { // 当第3个参数大于$k1时,或者第4个参数小于$k1时.
continue;
}
$this->data[$k1][$k2] = '#';
}
}
}

function draw() {
foreach ($this->data as $line) {
foreach ($line as $char) {
echo $char;
}
echo "\n";
}
}

}

实例化执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

require_once 'Loader.php';

$c = new Canvas;
$c->init();

// $c2 = new Canvas; // 传统开发模式,会直接实例化
// $c2->init();

$c2 = clone $c; // clone 会更加节省内容和资源消耗
$c2->rect(2,8,2,8);
$c2->draw();

$c3 = clone $c;
$c3->rect(1,8,4,8);
$c3->draw();

注册模式

注册模式目的是为了全局对象的共享和交换,即将创建好的对象挂在一个全局数组中,在需要的时候从该数组获得即可。

就要求在系统初始化时,一起初始化这个数组,并且保持数据不会被清理掉。

代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

class Register {

protected static $objects;

function set($alias, $object) {
self::$objects[$alias] = $object;
}

static function get($alias) {
return self::$objects[$alias];
}

function _unset($alias) {
unset(self::$objects[$alias]);
}

}

单例模式

  • $instance 必须声明为静态的私有变量。
  • 构造函数和析构函数必须声明为私有,防止外部程序new类而失去单例模式的意义
  • getInstance()方法必须设置为共有的,必须调用此方法以返回实例的一个引用
  • :: 操作符只能访问静态变量和静态函数
  • new对象都存在内存消耗(因为static方法,默认会占用部分内存)
  • 使用场景:最常用的地方是数据库连接 (仅存在一个实例,且不会创建其他实例)
  • 使用单例模式生成一个对象后,该对象可以被其他众多对象所使用
  • 私有的clone()方法防止克隆对象 (指的是魔术方法clone())

单例模式,使用某个类的对象在内存中仅允许存在一个。

构造函数private修饰,申明一个static getInstance方法,在该方法里创建该对象的实例,如果实例已存在,则不创建。

代码实例

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
<?php

class SingleTest {

static private $instance;
static private $config;

private function __construct($config) {
$this->config = $config;
echo "实例化成功";
}

private function __clone() {

}

static public function getInstance($config) {
if (!self::$instance instanceof self) {
self::$instance = new self($config);
}
return self::$instance;
}

public function getName() {
echo $this->config;
}

}

$single1 = SingleTest::getInstance('Hello World');
$single1->getName();

$single2 = SingleTest::getInstance('aaa');
$single2->getName();

后记

设计模式其实是对整个项目的把控,从基本功能的抽象开始,到一层层地封装,最后实现的是一套灵活性大可拓展性高的系统,不必因为小的改动而牵一发动全身。

但总结起来还是前文提到的,是为了学习编程,而非编程语言。