4种常见的 PHP 设计模式

工厂模式

在大型系统中,许多代码依赖于少数几个关键类。须要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您但愿将其更改成从数据库读取的其余类,可是,全部的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。php

工厂模式 是一种类,它具备为您建立对象的某些方法。您可使用工厂类建立对象,而不直接使用 new。这样,若是您想要更改所建立的对象类型,只需更改该工厂便可。使用该工厂的全部代码会自动更改。mysql

清单 1 显示工厂类的一个示列。等式的服务器端包括两个部分:数据库和一组 PHP 页面,这些页面容许您添加反馈、请求反馈列表并获取与特定反馈相关的文章。算法

清单 1. Factory1.phpsql

1数据库

2设计模式

3服务器

4并发

5测试

6ui

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

<?php

interface IUser

{

  function getName();

}

 

class User implements IUser

{

  public function __construct( $id ) { }

 

  public function getName()

  {

    return "Jack";

  }

}

 

class UserFactory

{

  public static function Create( $id )

  {

    return new User( $id );

  }

}

 

$uo = UserFactory::Create( 1 );

echo$uo->getName()."\n" );

?>

  

单元素模式(单列模式)

某些应用程序资源是独占的,由于有且只有一个此类型的资源。例如,经过数据库句柄到数据库的链接是独占的。您但愿在应用程序中共享数据库句柄,由于在保持链接打开或关闭时,它是一种开销,在获取单个页面的过程当中更是如此。

单元素模式能够知足此要求。若是应用程序每次包含且仅包含一个对象,那么这个对象就是一个单元素(Singleton)。清单 3 中的代码显示了 PHP V5 中的一个数据库链接单元素。

  1. php的应用主要在于数据库应用, 一个应用中会存在大量的数据库操做, 在使用面向对象的方式开发时, 若是使用单例模式, 则能够避免大量的new 操做消耗的资源,还能够减小数据库链接这样就不容易出现 too many connections状况。
  2. 若是系统中须要有一个类来全局控制某些配置信息, 那么使用单例模式能够很方便的实现. 这个能够参看zend Framework的FrontController部分。
  3. 在一次页面请求中, 便于进行调

清单 3. Singleton.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

<?php

require_once("DB.php");

 

class DatabaseConnection

{

  public static function get()

  {

    static $db = null;

    if $db == null )

      $db new DatabaseConnection();

    return $db;

  }

 

  private $_handle = null;

 

  private function __construct()

  {

    $dsn 'mysql://root:password@localhost/photos';

    $this->_handle =& DB::Connect( $dsnarray() );

  }

   

  public function handle()

  {

    return $this->_handle;

  }

}

 

print"Handle = ".DatabaseConnection::get()->handle()."\n" );

print"Handle = ".DatabaseConnection::get()->handle()."\n" );

?>

  您可使用全局变量存储数据库句柄,可是,该方法仅适用于较小的应用程序。在较大的应用程序中,应避免使用全局变量,并使用对象和方法访问资源。

观察者模式

观察者模式为您提供了避免组件之间紧密耦合的另外一种方法。该模式很是简单:一个对象经过添加一个方法(该方法容许另外一个对象,即观察者 注册本身)使自己变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操做与可观察的对象无关。结果是对象能够相互对话,而没必要了解缘由。

一个简单示例是系统中的用户列表。清单 4 中的代码显示一个用户列表,添加用户时,它将发送出一条消息。添加用户时,经过发送消息的日志观察者能够观察此列表。

清单 4. Observer.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

<?php

interface IObserver

{

  function onChanged( $sender$args );

}

 

interface IObservable

{

  function addObserver( $observer );

}

 

class UserList implements IObservable

{

  private $_observers array();

 

  public function addCustomer( $name )

  {

    foreach$this->_observers as $obs )

      $obs->onChanged( $this$name );

  }

 

  public function addObserver( $observer )

  {

    $this->_observers []= $observer;

  }

}

 

class UserListLogger implements IObserver

{

  public function onChanged( $sender$args )

  {

    echo"'$args' added to user list\n" );

  }

}

 

$ul new UserList();

$ul->addObserver( new UserListLogger() );

$ul->add

  

此代码定义四个元素:两个接口和两个类。IObservable 接口定义能够被观察的对象,UserList 实现该接口,以便将自己注册为可观察。IObserver 列表定义要经过怎样的方法才能成为观察者,UserListLogger 实现 IObserver 接口。图 4 的 UML 中展现了这些元素。

图 4. 可观察的用户列表和用户列表事件日志程序

 

若是在命令行中运行它,您将看到如下输出:

% php observer.php 
'Jack' added to user list
%

测试代码建立 UserList,并将 UserListLogger 观察者添加到其中。而后添加一个消费者,并将这一更改通知 UserListLogger

认识到 UserList 不知道日志程序将执行什么操做很关键。可能存在一个或多个执行其余操做的侦听程序。例如,您可能有一个向新用户发送消息的观察者,欢迎新用户使用该系统。这种方法的价值在于 UserList 忽略全部依赖它的对象,它主要关注在列表更改时维护用户列表并发送消息这一工做。

此模式不限于内存中的对象。它是在较大的应用程序中使用的数据库驱动的消息查询系统的基础。

 

策略模式

咱们讲述的最后一个设计模式是策略 模式。在此模式中,算法是从复杂类提取的,于是能够方便地替换。例如,若是要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 —— 一部分遍历页面,一部分对每页排列,另外一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。经过使用策略模式,您可将排列部分放入另外一个类中,以便更改页排列的方式,而不影响搜索引擎的其他代码。

清单 5. Strategy.php

相关文章
相关标签/搜索