php 设计模式备忘

  1. 单例模式用于:

        不重复建立对象,节省内存。(PHP很容易卡死的,比如说递归20,30 层)比如用于数据库连接对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Single {
    private $name;//声明一个私有的实例变量
    private function __construct(){//声明私有构造方法为了防止外部代码使用new来创建对象。
     
    }
 
    static public $instance;//声明一个静态变量(保存在类中唯一的一个实例)
    static public function getinstance(){//声明一个getinstance()静态方法,用于检测是否有实例对象
        if(!self::$instance) self::$instance new self();
        return self::$instance;
    }
 
    public function setname($n){ $this->name = $n; }
    public function getname(){ return $this->name; }
}

2.工厂模式用于:

        应该TP里面的M方法建立迷行应该就是这样,感觉和单例还是很像的。

        工厂模式就是一种类,具有为您创建对象的某些方法,这样就可以使用工厂类创建对象,而不直接使用new。这样如果想更改创建的对象类型,只需更改该工厂即可。

1
2
3
4
5
6
7
8
 class Factory {//创建一个基本的工厂类 
     static public function fac($id){//创建一个返回对象实例的静态方法 
         if(1 == $idreturn new A(); 
         elseif(2==$idreturn new B();
         elseif(3==$idreturn new C(); 
         return new D(); 
 
 }

3.观察者模式:

        针对一个博主,这是一个接口或者对象,里面可以注册观察者(关注者),然后遍历关注者,对每个人执行一个方法。例如这个样子:

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
<?php
    //主题
    class Paper{
        private $_observers array();
 
        //注冊观察者,谁依赖我,谁是我的粉丝,我有动态,依次推送,都在观察关注我
        public function register($sub){
            $this->_observers[] = $sub
        }
 
        //外部统一访问
        public function trigger(){
            if(!empty($this->_observers)){
                foreach($this->_observers as $observer){
                    $observer->update();//统一的方法,依次进行各个观察者
                }
            }
 
        }
    }
 
    //观察者实现接口
 
    interface Observerable{
        public function update();
    }
 
    class Subscriber implements Observerable{
        public function update(){
            echo "Callback\n";
        }
    }
 
    $paper new Paper();
 
    $paper->register(new Subscriber());
    $paper->trigger();

4.策略模式

针对同一个行为,你有不同的方案,就可以写成策略,就是一个大的算法集合。再比如你定价有不同的活动,满200-10,满400-100等,都是一个小算法,集合成策略

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
<?php
    interface FlyBehavior{
        //策略接口
        public function fly();
    }
 
    class FlyWithWings implements FlyBehavior{
        //c策略1
        public function fly(){
            echo "Fly with Wings";
        }
    }
 
    class FlyWithNo implements FlyBehavior{
        //c策略2
        public function fly(){
            echo "Fly with No Wings";
        }
    }
 
    class Duck{
        private $_flyBehavior;
        public function performFly(){
            $this->_flyBehavior->fly();
        }
        //这里引进来策略,可以切换不同的策略
        public function setFlyBehavior(FlyBehavior $behavior){
            $this->_flyBehavior = $behavior;
        }
    }
 
    class RubberDuck extends Duck{
 
    }
 
    $duck new RubberDuck();
    $duck->setFlyBehavior(new FlyWithWings());
    $duck->performFly();
 
    $duck->setFlyBehavior(new FlyWithWings());
    $duck->performFly();

5.装饰者模式

就是给被装饰者增加属性的,之后你就可以取代被装饰者。其实一个明显的例子就是穿衣服的顺序和方案。因为你有很多的方案可以动态加进去。这样的话比生成子类好很多,就不用把每个方案都建立对象,然后执行方法。

不恰当的示例如下:

$a = new a(new person());

$a.show();

$b=new b(new person());

$b.show();

$c = new c(new person());

$c.show();

改进的方案如下:首先把a,b,c 写一个抽象的接口统一起来,然后在面对被装饰者person()

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
<?php
    //抽象类不能实例化
    abstract class Beverage{
        public $_name;//品类名
        abstract public function Cost();//费用
    }
 
    //被装饰者,都是给coffee加东西
    class Coffee extends Beverage{
        public function __construct(){
            $this->_name = 'Coffee';//品类名
        }
        public  function Cost(){
            return 1.00;//原味咖啡的底价
        }
    }
 
    //以下三个类是装饰者相关类
    class CondimentDecorator extends Beverage{
        public function __construct(){
            $this->_name = 'Condiment';
        }
        public function Cost(){
            return 0.1;
        }
    }
 
    class Milk extends CondimentDecorator{
        public $_beverage;//被装饰者
        public function __construct($beverage){
            $this->_name = 'Milk';//该品种名
            if($beverage instanceof Beverage){
                $this->_beverage = $beverage;
            }else{
                exit('Failure');
            }
        }
 
        public function Cost(){
            return $this->_beverage->Cost()+0.2;//底价加上新加的东西
        }
    }
 
    class Sugar extends CondimentDecorator{
        public $_beverage;//被装饰者
        public function __construct($beverage){
            $this->_name = 'Sugar';//该品种名
            if($beverage instanceof Beverage){
                $this->_beverage = $beverage;
            }else{
                exit('Failure');
            }
        }
 
        public function Cost(){
            return $this->_beverage->Cost()+0.2;//底价加上新加的东西
        }
    }
 
    //拿杯咖啡
    $coffee new Coffee();
    //加点牛奶
    $coffee new Milk($coffee);
    //加点糖
    $coffee new Sugar($coffee);
 
    echo "Coffee现在的总价格是".$coffee->Cost();
 
    //总结:
    //1.装饰者和被装饰者必须是同一类型,因为装饰者可以取代它
    //2.当装饰者和组件组合的时候,就是在加入新的行为


上一篇:09 Hive安装与操作


下一篇:09 Hive安装与操作