1.工厂模式
成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站制作、网站建设、外贸网站建设、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的清镇网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
工厂模式是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。
2.单元素模式
某些应用程序资源是独占的,因为有且只有一个此类型的资源。例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更是如此。
3.观察者模式
观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可 以相互对话,而不必了解原因。
4.命令链模式
命令链 模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。
5.策略模式
我们讲述的最后一个设计模式是策略 模式。在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎 的几个部分 —— 一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个 类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。
PHP 一般有五种常见的设计模式
工厂模式
工厂模式 是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。
例如:
?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)。
例如:
?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" );
?
观察者模式
观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。
例如:
?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-addCustomer( "Jack" );
?
命令链模式
命令链 模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。
例如:
?php
interface ICommand
{
function onCommand( $name, $args );
}
class CommandChain
{
private $_commands = array();
public function addCommand( $cmd )
{
$this-_commands []= $cmd;
}
public function runCommand( $name, $args )
{
foreach( $this-_commands as $cmd )
{
if ( $cmd-onCommand( $name, $args ) )
return;
}
}
}
class UserCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'addUser' ) return false;
echo( "UserCommand handling 'addUser'\n" );
return true;
}
}
class MailCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'mail' ) return false;
echo( "MailCommand handling 'mail'\n" );
return true;
}
}
$cc = new CommandChain();
$cc-addCommand( new UserCommand() );
$cc-addCommand( new MailCommand() );
$cc-runCommand( 'addUser', null );
$cc-runCommand( 'mail', null );
?
策略模式
我们讲述的最后一个设计模式是策略 模式。在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 —— 一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。
例如:
?php
interface IStrategy
{
function filter( $record );
}
class FindAfterStrategy implements IStrategy
{
private $_name;
public function __construct( $name )
{
$this-_name = $name;
}
public function filter( $record )
{
return strcmp( $this-_name, $record ) = 0;
}
}
class RandomStrategy implements IStrategy
{
public function filter( $record )
{
return rand( 0, 1 ) = 0.5;
}
}
class UserList
{
private $_list = array();
public function __construct( $names )
{
if ( $names != null )
{
foreach( $names as $name )
{
$this-_list []= $name;
}
}
}
public function add( $name )
{
$this-_list []= $name;
}
public function find( $filter )
{
$recs = array();
foreach( $this-_list as $user )
{
if ( $filter-filter( $user ) )
$recs []= $user;
}
return $recs;
}
}
$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );
$f1 = $ul-find( new FindAfterStrategy( "J" ) );
print_r( $f1 );
$f2 = $ul-find( new RandomStrategy() );
print_r( $f2 );
?
《PHP设计模式介绍》第八章 迭代器模式
类中的面向对象编程封装应用逻辑 类 就是实例化的对象 每个单独的对象都有一个特定的身份和状态 单独的对象是一种组织代码的有用方法 但通常你会处理一组对象或者集合
属性来自 SQL 查询的一组数据就是一个集合 就像本书前面章节介绍的 Monopoly 游戏示例的对象列表
集合不一定是均一的 图形用户界面框架中的 Window 对象可以收集任意数量的控制对象 - Menu Slider 和 Button 并且 集合的实现可以有多种方式 PHP 数字是一个集合 但也是一个散列表 一个链接列表 一个堆栈以及队列
问题
如何操纵任意的对象集合?
解决方案
使用迭代器模式来提供对集合内容的统一存取
你可能没有意识到这一点 但你每天都在使用迭代器模式 - 它潜藏在 PHP 的数组类型和各种数组操作函数中 (其实 给你一些固有类的数组的组合和一群用这些固有类工作的可变函数 你将不得不使用这些数组来处理对象集合 这是在 PHP 中的本地数组迭代
$test = array( one o three );$output = ; reset($test); do {$output = current($test);} while (next($test));echo $output; // produces oneothree
reset() 函数将迭代重新转到数组的开始 current() 返回当前元素的值 next() 则前进至数组中的下一个元素并返回新的 current() 值 当你超出数组的最后一个元素时 next() 返回 false 使用这些迭代方法 PHP 数组的内部实现就与你不相关了 迭代器结合了封装和多态的面向对象程序设计原理 使用迭代器 你可以对集合中的对象进行操作 而无需专门了解集合如何显现或者集合包含什么(对象的种类) 迭代器提供了不同固定迭代实现的统一接口 它完全包含了如何操纵特定集合的详细信息 包括显示哪些项(过滤)及其显示顺序(排序)
让我们创建一个简单的对象 在数组中对它进行操作 (尽管该示例在 PHP 环境下 但迭代器并不特定于 PHP 虽然添加了较多的引用操作符 本章节中的大多数示例在 PHP 下也能够运行) 对象 Lendable 表示诸如电影 相册等媒体 它作为 Web 站点的一部分或服务 允许用户浏览或将他们的媒体集合分享给其他用户 (对 于该示例 请无需考虑其他方面 )让我们开始下面对 Lendable 基础设计的测试
// PHP class LendableTestCase extends UnitTestCase {function TestCheckout() {$item = new Lendable;$this assertFalse($item borrower);$item checkout( John );$this assertEqual( borrowed $item status);$this assertEqual( John $item borrower);}function TestCheckin() {$item = new Lendable;$item checkout( John );$item checkin();$this assertEqual( library $item status);$this assertFalse($item borrower);}}
要实现这一最初测试的需求 我们来创建一个带有若干公共属性和一些方法的类 来触发这些属性的值
class Lendable {public $status = library ;public $borrower = ;public function checkout($borrower) {$this status = borrowed ;$this borrower = $borrower;}public function checkin() {$this status = library ;$this borrower = ;}}
Lendable 是一个好的 普通的开端 让我们将它扩展到诸如 DVD 或 CD 的磁道项 媒体扩展了 Lendable 并且磁道详细记录了特定媒体的详细信息 包括项目的名称 发布的年份以及项本身的类型
class Media extends Lendable {public $name; public $type; public $year;public function __construct($name $year $type= dvd ) {$this name = $name;$this type = $type;$this year = (int)$year;}}
要使事情更加简单 媒体有三个公共的实例变量 Media::name Media::year 和Media::type 构造函数采用了两个参数 将第一个存储在 $name 中 第二个存储在 $year 中 构造函数还允许可选的第三个参数来指定类型(缺省为dvd)
给定单独的对象来操作 你现在可以创建一个容器来包含他们 Library 类似于常用的库 Library 应该能够添加 删除和计算集合中的项 甚至 Library 还应该允许访问集合(本章中的样本代码部分可看到示例)中的单一的项(对象)
我们开始构建 Library 的测试用例
class LibraryTestCase extends UnitTestCase {function TestCount() {$lib = new Library;$this assertEqual( $lib count());}}
它是满足这一测试的简单类
class Library {function count() {return ;}}
继续将一些有趣的功能添加到测试中
class LibraryTestCase extends UnitTestCase {function TestCount() { /* */ }function TestAdd() {$lib = new Library;$lib add( one );$this assertEqual( $lib count());}}
实现 add() 的简单方法是建立在 PHP 灵活数组函数的基础上 你可以将项添加到实例变量并使用 count() 来返回集合众项的数量
class Library {protected $collection = array();function count() {return count($this collection);}function add($item) {$this collection[] = $item;}}
lishixinzhi/Article/program/net/201311/13092