原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=12
可以在线运行查看效果哦!
在上一篇我们讲了结构型模式,结构型模式是讨论类和对象的结构的。总共有7种。而今天我们来介绍一下行为型模式。
一、什么是行为型模式?
行为型模式:
就是描述类和对象之间的通信和职责的。简而言之,就是类和对象扮演什么角色,还有怎么扮演这个角色的问题。
二、行为型模式的种类
大体上分为三个大类:常见模式、已知模式、深度模式
常见模式包括: 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、状态模式、职责链模式、策略模式
已知模式包括:备忘录模式
深度模式包括:解释器模式、访问者模式
常见模式
1、模版方法模式(Template):
定义一个操作中的算法骨架,而将一些实现步骤延迟到子类当中实现。就像一个豆浆机,不管放进去的是红豆还是黑豆,出来的都是豆浆。
好处:扩展性好,封装不变的代码,扩展可变的代码。
弊端:灵活性差,不能改变骨架部分。
应用场景:一类或一组具有共性的事物中。
代码实现
<?php /** * 优才网公开课示例代码 * * 模板方法模式 Template * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Request { public $token = ''; public function __construct() { $this->token = '0c6b7289f5334ed2b697dd461eaf9812'; } } class Response { public function render($content) { output(sprintf('response-render: %s', $content)); } public function redirect($uri) { output(sprintf('response-redirect: %s', $uri)); } public function json($data) { output(sprintf('response-data: %s', json_encode($data))); } } //父类,抽象类 abstract class Controller{ //封装了输入输出 protected $request; protected $response; //返回数据 protected $data = 'data'; public function __construct($request, $response){ $this->request = $request; $this->response = $response; } //执行请求函数,定义总体算法(template method),final防止被复写(不允许子类改变总体算法) public final function execute(){ $this->before(); if ($this->valid()){ $this->handleRequest(); } $this->after(); } //定义hook method before,做一些具体请求的前置处理 //非abstract方法,子类可以选择覆盖或不覆盖,默认什么都不做 protected function before(){ } //定义hook method valid,做请求的数据验证 //非abstract方法,子类可以选择覆盖或不覆盖,默认返回验证通过 protected function valid(){ return true; } //定义hook method handleRequest,处理请求 //定义为abstract方法,子类必须实现或也声明为抽象方法(由子类的子类负责实现) abstract function handleRequest(); //定义hook method after,做一些请求的后置处理 //非abstract方法,子类可以选择覆盖或不覆盖,默认直接输出数据 protected function after(){ $this->response->render($this->data); } } //子类1,实现父类开放的具体算法 class User extends Controller{ //覆盖before方法,实现具体算法,这是一个处理用户数据操作的控制器 //因此,我们选择在before里面判断用户是否已经登录了,这里简单判断下session数据 function before(){ if (empty($_SESSION['auth'])){ //没登录就直接跳转了,不再执行后续的操作 $this->response->redirect("user/login.php"); } } //覆盖valid方法,这里我们验证用户提交数据中有没有带验证token function valid(){ if (isset($this->request->token)){ return true; } return false; } //覆盖handleRequest方法,必选,以为父类中声明了abstract了 function handleRequest(){ //做具体处理,一般根据参数执行不同的业务逻辑 } //这个类我们选择不覆盖after方法,使用默认处理方式 } //子类2,实现父类开放的具体算法 class Post extends Controller{ //这个类我们选择不覆盖before方法,使用默认处理方式 //这个类我们选择不覆盖valid方法,使用默认处理方式 //覆盖handleRequest方法,必选,以为父类中声明了abstract了 function handleRequest(){ //做具体处理,一般根据参数执行不同的业务逻辑 $this->data = array('title' => 'ucai'); } //覆盖after方法,使用json格式输出数据 function after(){ $this->response->json($this->data); } } class Client { public static function test(){ $request = new Request(); $response = new Response(); //最终调用 $user = new User($request, $response); $user->execute(); //最终调用 $post = new Post($request, $response); $post->execute(); } } Client::test();
2、命令模式(Command) :
行为请求者与行为实现者解耦。就像军队里的“敬礼”,不管是谁听到这个命令都会做出标准的敬礼动作。
好处:便于添加和修改行为,便于聚合多个命令。
弊端:造成过多具体的命令类。
应用场景:对要操作的对象,进行的相同操作。
代码实现
<?php /** * 优才网公开课示例代码 * * 命令模式 Command * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Document { private $name = ''; public function __construct($name) { $this->name = $name; } public function showText() { output(sprintf("showText: %s", $this->name)); } public function undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics { private $name = ''; public function __construct($name) { $this->name = $name; } public function drawCircle() { output(sprintf("drawCircle: %s", $this->name)); } public function undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class Client { public static function test() { $document = new Document('A'); $graphics = new Graphics('B'); $document->showText(); $graphics->drawCircle(); $document->undo(); } } Client::test(); <?php /** * 优才网公开课示例代码 * * 命令模式 Command * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } interface Command { public function execute(); public function undo(); } class Document implements Command { private $name = ''; public function __construct($name) { $this->name = $name; } public function execute() { output(sprintf("showText: %s", $this->name)); } public function undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics implements Command { private $name = ''; public function __construct($name) { $this->name = $name; } public function execute() { output(sprintf("drawCircle: %s", $this->name)); } public function undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class Client { public static function test() { $array = array(); array_push($array, new Document('A')); array_push($array, new Document('B')); array_push($array, new Graphics('C')); array_push($array, new Graphics('D')); foreach ($array as $command) { $command->execute(); } $top = array_pop($array); $top->undo(); } } Client::test(); <?php /** * 优才网公开课示例代码 * * 命令模式 Command * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } interface Command { public function execute(); public function undo(); } class Document { private $name = ''; public function __construct($name) { $this->name = $name; } public function showText() { output(sprintf("showText: %s", $this->name)); } public function undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics { private $name = ''; public function __construct($name) { $this->name = $name; } public function drawCircle() { output(sprintf("drawCircle: %s", $this->name)); } public function undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class DocumentCommand implements Command { private $obj = ''; public function __construct(Document $document) { $this->obj = $document; } public function execute() { $this->obj->showText(); } public function undo() { $this->obj->undo(); } } class GraphicsCommand implements Command { private $obj = ''; public function __construct(Graphics $graphics) { $this->obj = $graphics; } public function execute() { $this->obj->drawCircle(); } public function undo() { $this->obj->undo(); } } class Client { public static function test() { $array = array(); array_push($array, new DocumentCommand(new Document('A'))); array_push($array, new DocumentCommand(new Document('B'))); array_push($array, new GraphicsCommand(new Graphics('C'))); array_push($array, new GraphicsCommand(new Graphics('D'))); foreach ($array as $command) { $command->execute(); } $top = array_pop($array); $top->undo(); } } Client::test();
3、迭代器模式(Iterator):
访问聚合对象内容而不暴露内部结构。就像一个双色球彩票开奖一样,每次都是摇出七个球,不能能摇不是七个球的中奖号码组合。
好处:以不同方式遍历一个集合。
弊端:每次遍历都是整个集合,不能单独取出元素。
应用场景:需要操作集合里的全部元素。
代码实现
<?php /** * 优才网公开课示例代码 * * 迭代器模式 Iterator * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } class RecordIterator implements Iterator{ private $position = 0; //注意:被迭代对象属性是私有的 private $records = array(); public function __construct(Array $records) { $this->position = 0; $this->records = $records; } function rewind() { $this->position = 0; } function current() { return $this->records[$this->position]; } function key() { return $this->position; } function next() { ++$this->position; } function valid() { return isset($this->records[$this->position]); } } class PostListPager { protected $record = array(); protected $total = 0; protected $page = 0; protected $size = 0; public function __construct($category, $page, $size) { $this->page = $page; $this->size = $size; // query db $total = 28; $this->total = $total; $record = array( 0 => array('id' => '1'), 1 => array('id' => '2'), 2 => array('id' => '3'), 3 => array('id' => '4'), ); // $this->record = $record; } public function getIterator() { return new RecordIterator($this->record); } public function getMaxPage() { $max = intval($this->total / $this->size); return $max; } public function getPrevPage() { return max($this->page - 1, 1); } public function getNextPage() { return min($this->page + 1, $this->getMaxPage()); } } class Client { public static function test(){ $pager = new PostListPager(1, 2, 4); foreach ($pager->getIterator() as $key => $val) { output(sprintf('Key[%d],Val[%s]', $key, json_encode($val))); } output(sprintf('MaxPage[%d]', $pager->getMaxPage())); output(sprintf('Prev[%d]', $pager->getPrevPage())); output(sprintf('Next[%d]', $pager->getNextPage())); $iterator = $pager->getIterator(); while($iterator->valid()){ print_r($iterator->current()); $iterator->next(); } $iterator->rewind(); } } Client::test();
优才免费公开课链接: http://www.ucai.cn/course5/
相关推荐
3. 行为型模式: - 责任链模式:避免将请求的发送者和接收者耦合在一起,使得多个对象都有可能处理请求。 - 命令模式:将请求封装为一个对象,以便使用不同的请求、队列请求、或者记录请求日志。 - 解释器模式:...
《PHP设计模式全解》是一本深入探讨PHP编程中设计模式的资源集合,它旨在帮助PHP开发者提升代码质量、可维护性和复用性。设计模式是软件工程中的宝贵经验总结,通过将常见的问题解决方案标准化,使得开发过程更加...
2. PHP设计模式的类型:PHP中常用的设计模式可以分为三大类,分别是创建型模式、结构型模式和行为型模式。创建型模式主要涉及对象实例化的过程,如单例模式、工厂模式、建造者模式等;结构型模式涉及如何组合类和...
本资源包含了《PHP设计模式》一书中的实际代码示例,这些例程涵盖了多种设计模式,包括创建型、结构型和行为型模式。通过这些源码,开发者可以更直观地学习如何在实际项目中应用这些模式。 1. **创建型模式**: - ...
14. 状态模式:允许对象在其内部状态改变时改变其行为。它将条件分支逻辑封装到独立的类中,使代码更易于理解和维护。 15. 模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。它使得子类可以不...
《PHP设计模式》是一本探讨如何在PHP编程中应用设计模式的书籍。设计模式是软件工程领域中,解决常见问题的模板或策略。本书作者是美国的Aaron Saray,内容详尽地介绍了各种设计模式,旨在帮助PHP开发者构建出更加...
《Learning PHP设计模式》这本书为PHP开发者提供了一个深入理解并应用设计模式的宝贵资源。 该书中文翻译版于2014年首次在中国出版,由电力出版社发行,以清晰的PDF格式呈现,便于读者阅读和查阅。目录结构完整,...
PHP设计模式主要分为三大类:创建型模式、结构型模式和行为型模式。 1. **创建型模式**: - 单例模式:确保一个类只有一个实例,并提供一个全局访问点。 - 工厂模式:提供一个接口来创建对象,但让子类决定实例化...
5. **观察者模式**(Observer):这种行为模式定义了对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在事件驱动编程中非常常见。 6. **策略模式**:策略模式定义...
PHP设计模式是将这些模式应用到PHP编程中的具体实现,可以帮助开发者编写更灵活、可维护和高效的代码。以下是对标题和描述中提及的一些设计模式的详细说明: 1. **解释器设计模式**:它允许我们创建一个简单的语言...
3. 观察者模式:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 4. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体...
以上只是PHP设计模式中的一部分,每种模式都有其适用的场景和价值。通过学习和应用这些设计模式,开发者可以写出更高效、更具扩展性和易于维护的代码。在实际项目中,根据需求灵活选择和组合设计模式,可以显著提高...
《PHP设计模式》一书由美国作者Aaron Saray撰写,主要针对PHP开发者,详细阐述了在实际编程过程中如何运用设计模式提升代码质量和可维护性。设计模式是软件工程中的最佳实践,它们是解决常见问题的经验总结,使得...
例如,工厂模式、单例模式、观察者模式等,都是在PHP开发中经常用到的设计模式。通过理解这些模式,开发者可以写出更灵活、可扩展的代码,并且能够更好地与其他开发者协作。 再者,“框架”章节会介绍一些流行的PHP...
这个压缩包很可能包含了关于如何在PHP项目中应用设计模式的资料,特别是针对"designpatterns-php-master"这个文件名,我们可以推测这可能是一个关于PHP设计模式的开源项目或教程。 设计模式并不直接是代码,而是一...
3. 行为型模式:这类模式关注对象之间的交互和职责分配,包括责任链(Chain of Responsibility)、命令(Command)、解释器(Interpreter)、迭代器(Iterator)、备忘录(Memento)、观察者(Observer)、状态...
3. 行为型模式:如策略(Strategy)、模板方法(Template Method)、观察者(Observer)、责任链(Chain of Responsibility)、访问者(Visitor)、命令(Command)、迭代器(Iterator)、备忘录(Memento)、状态...
本资源包含的"php23种完整设计模式(完整代码)"是一个宝贵的学习资料,它涵盖了设计模式的全貌,让开发者可以通过实践来掌握这些模式。 首先,让我们逐一了解这23种设计模式,并讨论它们的核心思想和应用场景: 1...
10. 状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。 11. 命令模式:将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可...