4种常见的 PHP 设计模式

Wesley13
• 阅读 523

工厂模式

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

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

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

清单 1. Factory1.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

<?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( $dsn``, array``() );

}

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

点赞
收藏
评论区
推荐文章
happlyfox happlyfox
3年前
笑说设计模式-小白逃课被点名
关于我简介工厂模式(FactoryPattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。分类工厂模式可以分为三种,其中简单工厂一般不被认为是一种设计模式,可以将其看成是工厂方法的一种特殊
桃浪十七丶 桃浪十七丶
3年前
工厂模式实例(顺便回忆反射机制的应用)
一、原理反射机制的原理JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。工厂模式自述所谓工厂模式,是说由某个产品类接口、产品实现类、工厂类、客户端(单元测试主类)构成的一个模式,大程度的降低了代码的
Wesley13 Wesley13
3年前
Unity C# 设计模式(二)简单工厂模式
定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该
Wesley13 Wesley13
3年前
Java描述设计模式(04):抽象工厂模式
一、抽象工厂模式1、生活场景汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。2、抽象工厂模式1.抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;2.抽象工厂模式可以
Stella981 Stella981
3年前
Android Framework中的PolicyManager简介
PolicyManager类位于framework\\base\\core\\java\\com\\android\\internal\\policy目录中的PolicyManager.java文件中。PolicyManager主要用于创建Window类、LayoutInflater类和WindowManagerPolicy类,它扮演着简单工厂模式中的工厂类
Stella981 Stella981
3年前
Python之设计模式
一、设计模式分类a、创建型模式简单工厂模式一、内容不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。二、角色工厂角色(Creator)抽象产品角色(Product)具体产品角色(ConcreteProduct)
Stella981 Stella981
3年前
C#中Activator.CreateInstance()方法用法分析
本文实例讲述了C中Activator.CreateInstance()方法用法。Activator类包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。C在类工厂中动态创建类的实例,所使用的方法为:1.Activator.CreateInstance(Type)2.Activator.
Wesley13 Wesley13
3年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏
Wesley13 Wesley13
3年前
JS创建对象模式7种方法详解
创建对象的几种模式虽然Object构造函数或者字面量,都可以用来创建对象,但这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的代码,于是,工厂模式诞生了1工厂模式工厂模式是广为人知的设计模式,抽象了创建具体对象的过程。在ES6的Class创建类之前,是无法创建类的,开发人员就发明了一种函数,用函数来封
Wesley13 Wesley13
3年前
C++ 常用设计模式(学习笔记)
设计模式1、工厂模式在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。1.1、简单工厂模式主要特点是需要在工厂类中做判断,从而创造相应的产品,当