1. 解析器模式//解析器内容类
//用于存放表达式的运算结果,并且能依据传入的表达式返回当初记录的结果
class InterpreterContext{private $expressionstore=array();//将对象放进array里面,索引號是对象ID号function replace(Expression $exp,$value){$this->expressionstore[$exp->getKey()]=$value;}function lookup(Expression $exp){return $this->expressionstore[$exp->getKey()];}
}
abstract class Expression{private static $keyCount=0;private $key;abstract function interpret(InterpreterContext $context);//每个对象都有一个唯一的keyfunction getKey(){if(!isset($this->key)){$this->key=++self::$keyCount;}return $this->key;}
}
//字符串
class LiteralExpression extends Expression{private $value;function __construct($value){$this->value=$value;}function interpret(InterpreterContext $context){$context->replace($this, $this->value);}
}
//变量
class VariableExpression extends Expression{private $value;private $name;function __construct($name,$value=null){$this->name=$name;$this->value=$value;}function setValue($value){$this->value=$value;}function getKey(){return $this->name;}function interpret(InterpreterContext $context){if(!is_null($this->value)){$context->replace($this, $this->value);//设置为空,能够避免在没有修改value的情况下再次调用该方法的时候,//也第二次调用了InterpreterContext::replece$this->value=null;}}
}
//操作符表达式 抽象基类
abstract class OperatorExpression extends Expression{//左右操作数protected $l_op;protected $r_op;function __construct(Expression $l_op,Expression $r_op){$this->l_op=$l_op;$this->r_op=$r_op;}function interpret(InterpreterContext $context){$this->l_op->interpret($context);$this->r_op->interpret($context);$result_l=$context->lookup($this->l_op);$result_r=$context->lookup($this->r_op);$this->doInterpret($context, $result_l, $result_r);}protected abstract function doInterpret(InterpreterContext $context,$result_l,$result_r);
}
//相等表达式
class EqualsExpression extends OperatorExpression{//计算后将结果保存进this里...protected function doInterpret(InterpreterContext $context,$result_l,$result_r){$context->replace($this, $result_l==$result_r);}
}
//布尔或表达式
class BooleanOrExpression extends OperatorExpression{protected function doInterpret(InterpreterContext $context, $result_l, $result_r){$context->replace($this, $result_l || $result_r);}
}
//布尔与表达式
class BooleanAndExpression extends OperatorExpression{protected function doInterpret(InterpreterContext $context, $result_l, $result_r){$context->replace($this, $result_l && $result_r);}
}
/*
$context=new InterpreterContext();
$literal=new LiteralExpression("Bob");
$literal->interpret($context);
print $context->lookup($literal);//Bob
$context=new InterpreterContext();
$myvar=new VariableExpression("V","one");
$myvar->interpret($context);
print $context->lookup($myvar);//one
$myothervar=new VariableExpression("V");
$myvar->interpret($context);
print $context->lookup($myvar);//one
*/
//利用上面的代码来检測迷你型语言
//$input equals "4" or $input equals "four"
$context=new InterpreterContext();
//一个没有赋值的变量
$input=new VariableExpression('input');
//定义一个复杂的布尔型变量,初始化的參数被保存在l_op,r_op里面
//注意,此时他们还没有进行相关运算,必须等到调用布尔型变量的interpret()
//之后,布尔型变量里面的參数才会各自调用自身的interpret,形成一个调用栈...
$statement=new BooleanOrExpression(new EqualsExpression($input, new LiteralExpression('four')), new EqualsExpression($input, new LiteralExpression('4')));
$statement->interpret($context);
print $context->lookup($statement);
foreach (array('four','4','52') as $val){$input->setValue($val);print "$val:\n";$statement->interpret($context);if($context->lookup($statement)){print "top marks\n";}else{print "dunce hat on\n\n";}
}
/*four:
top marks
4:
top marks
52:
dunce hat on*/  2.策略模式将类中很多不同操作并且是来自同一个接口的算法,独立起来封装在一个新类中,主类在由分类组合或者聚合而成//Question类将由Marker聚合而成
abstract class Question{protected $prompt;protected $marker;function __construct($prompt,Marker $marker){$this->marker=$marker;$this->prompt=$prompt;}//利用托付实现function mark($response){return $this->marker->mark($response);}
}
class TextQuestion extends Question{//处理文本问题特有的操作
}
class AVQuestion extends Question{//处理语音问题特有操作
}
//策略对象
//将算法部分独立出来封装在Marker类中....
abstract class Marker{protected $test;function __construct($test){$this->test=$test;}abstract function mark($response);
}
//MarkLogic语言
class MarkLogicMarker extends Marker{protected $engine;function __construct($test){parent::__construct($test);}function mark($response){//模拟返回truereturn true;}
}
//直接匹配
class MatchMarker extends Marker{function mark($response){return ($this->test==$response);}
}
//正則表達式
class RegexpMarker extends Marker{function mark($response){return (preg_match($this->test, $response));}
}
//client演示样例代码
$markers=array(new RegexpMarker("/f.ve/"),new MatchMarker("fivev"),new MarkLogicMarker('$input equals "five"'));
foreach($markers as $marker){print get_class($marker)."\n";//新建一个问题,将marker实例传进去$question=new TextQuestion("How many beans make five", $marker);foreach (array("five","four") as $response){print "\t response:$response: ";if($question->mark($response)){print "well done\n";}else{print "never mind\n";}}
}
/*RegexpMarkerresponse:five: well doneresponse:four: never mind
MatchMarkerresponse:five: never mindresponse:four: never mind
MarkLogicMarkerresponse:five: well doneresponse:four: well done
*/3 观察者模式观察者模式的和兴是把客户元素(观察者)从一个中心类中分离开来.当主体中有事件发生时,观察者必须被通知到!同一时候观察者和主体类不是通过硬编码实现,而是通过接口组合聚合实现
*问题
// Login类(主体类)
class Login {const LOGIN_USER_UNKNOWN = 1;const LOGIN_WRONG_PASS = 2;const LOGIN_ACCESS = 3;private $status = array ();// 登录操function handleLogin($user, $pass, $ip) {$ret=false;switch (rand ( 1, 3 )) {case 1 :$this->setStatus ( self::LOGIN_ACCESS, $user, $ip );$ret=ture;break;case 2 :$this->setStatus ( self::LOGIN_WRONG_PASS, $user, $ip );$ret=false;break;case 3 :$this->setStatus ( self::LOGIN_USER_UNKNOWN, $user, $ip );$ret=false;break;default:$ret=false;}//假设须要记录IP时Logger::logIP($user, $ip, $this->getStatus());//假设须要把登录失败的人的IP发送到管理员邮箱时...if(!$ret){Notifier::mailWarning($user, $ip, $this->getStatus());}//还须要其它功能时,比方特殊IP须要设置cookie等...//须要在这里面一直加入...return $ret;}function setStatus($status, $user, $ip) {$this->status = array ($status,$user,$ip);}function getStatus(){return $this->status;}
}
class Logger{static function logIP($user,$ip,$status){}
}
class Notifier{static function mailWarning($user,$ip,$status){}
}
*利用观察者模式,使代码修改少些....
// 主体类的抽象接口
interface Observable{//附加function attach(Observer $observer);//删除function detach(Observer $observer);//通知function notify();
}
// Login类(主体类)
class Login implements Observable{const LOGIN_USER_UNKNOWN = 1;const LOGIN_WRONG_PASS = 2;const LOGIN_ACCESS = 3;private $observers;private $status = array ();// 登录操作function handleLogin($user, $pass, $ip) {$ret=false;switch (rand ( 1, 3 )) {case 1 :$this->setStatus ( self::LOGIN_ACCESS, $user, $ip );$ret=ture;break;case 2 :$this->setStatus ( self::LOGIN_WRONG_PASS, $user, $ip );$ret=false;break;case 3 :$this->setStatus ( self::LOGIN_USER_UNKNOWN, $user, $ip );$ret=false;break;default:$ret=false;}//使用观察者模式之后,假设须要添加新功能,仅仅须要在本类中加入观察者实例就可以...$this->notify();return $ret;}function setStatus($status, $user, $ip) {$this->status = array ($status,$user,$ip);}function getStatus(){return $this->status;}function attach(Observer $observer){$this->observers[]=$observer;}function detach(Observer $observer){$newObserver=array();foreach ($this->observers as $obs){if($obs!==$observer){$newObserver[]=$obs;}}$this->observers=$newObserver;}//通知全部观察者function notify(){foreach ($this->observers as $bos){$bos->update($this);}}
}
//观察者接口
interface Observer{function update(Observable $observable);
}
class SecurityMonitor implements Observer{function update(Observable $observable){//getStatus()不是Observable接口规定的方法$status=$observable->getStatus();//对status的推断也涉及到耦合问题if($status[0]==Login::LOGIN_WRONG_PASS){//发送邮件给管理员print __CLASS__.":\t sending mail to sysadmin\n";}}
}
$login=new Login();
$login->attach(new SecurityMonitor());
$login->handleLogin("coco", "123456", "127.0.0.1");//有可能输出发送消息到管理员*改进后的观察者模式//可观察元素:主体类的基接口
interface Observable{//附加function attach(Observer $observer);//删除function detach(Observer $observer);//通知function notify();
}
// Login类(主体类)
class Login implements Observable{const LOGIN_USER_UNKNOWN = 1;const LOGIN_WRONG_PASS = 2;const LOGIN_ACCESS = 3;private $observers;private $status = array ();// 登录操作function handleLogin($user, $pass, $ip) {$ret=false;switch (rand ( 1, 3 )) {case 1 :$this->setStatus ( self::LOGIN_ACCESS, $user, $ip );$ret=ture;break;case 2 :$this->setStatus ( self::LOGIN_WRONG_PASS, $user, $ip );$ret=false;break;case 3 :$this->setStatus ( self::LOGIN_USER_UNKNOWN, $user, $ip );$ret=false;break;default:$ret=false;}//使用观察者模式之后,假设须要添加新功能,仅仅须要在本类中加入观察者实例就可以...$this->notify();return $ret;}function setStatus($status, $user, $ip) {$this->status = array ($status,$user,$ip);}function getStatus(){return $this->status;}function attach(Observer $observer){$this->observers[]=$observer;}function detach(Observer $observer){$newObserver=array();foreach ($this->observers as $obs){if($obs!==$observer){$newObserver[]=$obs;}}$this->observers=$newObserver;}//通知全部观察者function notify(){foreach ($this->observers as $bos){$bos->update($this);}}
}
//观察者接口
interface Observer{function update(Observable $observable);
}
//Login:观察者超类(用于解决直接在Observer中调用详细的Observable子类造成的风险)
abstract class LoginObserver implements Observer{private $login;function __construct(Login $login){$this->login=$login;$this->login->attach($this);}//该方法在Observable的子类某些方法被调用时触发function update(Observable $observable){//触发该方法时,传入的參数必须是Login才有效...if($this->login===$observable){$this->doUpdate($observable);}}abstract function doUpdate(Login $login);}
//改进后的观察者能保证调用的Observable实例方法一定存在
class SecurityMonitor extends LoginObserver{function doUpdate(Login $login){$status=$login->getStatus();//对status的推断也涉及到耦合问题if($status[0]==Login::LOGIN_WRONG_PASS){//发送邮件给管理员print __CLASS__.":\t sending mail to sysadmin\n";}}
}
//日常记录
class GeneralLogger extends LoginObserver{function doUpdate(Login $login){$status=$login->getStatus();//加入记录到log中//...print __CLASS__."\t add login data to log\n";}
}
//合作伙伴工具类
class PartnershipTool extends LoginObserver{function doUpdate(Login $login){$status=$login->getStatus();//检查IP,假设匹配,则设置cookie...//...print __CLASS__."\t set cookie if IP matches a list\n";}
}
//client代码有一点点改变...
$login=new Login();
new SecurityMonitor($login);
new GeneralLogger($login);
new PartnershipTool($login);
$login->handleLogin("coco", "123456", "127.0.0.1");
/** 有可能输出*SecurityMonitor:     sending mail to sysadmin*GeneralLogger     add login data to log*PartnershipTool    set cookie if IP matches a list**/4. 訪问者模式当使用对象集合时,我们可能须要对结构上每个单独的组件应用各种操作.这种操作能够内建于组件本身,毕竟组件内部调用其它组件是最方便的. 可是这个方案也存在问题,由于我们并不知道全部可能须要的运行的操作.假设每添加一个操作,就在类中添加一个对于新操作的支持,类就会变得越来越臃肿.訪问者模式能够解决问题.//本例是基于"文明"游戏的代码建立而成...
//*战斗单元类
abstract class Unit{//深度protected $depth=0;//攻击强度abstract function bombardStrength();function getComposite(){return null;}//为訪问者模式打造的方法function accept(ArmyVisitor $visitor){//构建一个依据自己规则定义的方法名,然后交给visitor自身调用$method="visit".get_class($this);$visitor->$method($this);}//用于计算Unit在对象树中的深度protected function setDepth($depth){$this->depth==$depth;}function getDepth(){return $this->depth;}
}
//复合抽象类
abstract class CompositeUnit extends Unit{protected $units=array();//为訪问者模式打造的方法function accept(ArmyVisitor $visitor){//构建一个依据自己规则定义的方法名,然后交给visitor自身调用//先调用父类accept(),再遍历调用子元素accept()parent::accept($visitor);foreach ($this->units as $thisunit){$thisunit->accept($visitor);}}//能够不用写bombardStrength()function getComposite(){return $this;}//加入单元//同一时候标记节点在对象树中的深度function addUnit(Unit $unit){if(!empty($unit)){if(in_array($unit, $this->units,true)){return;}//能够用以下代码替换in_array()函数
//             foreach ($this->units as $thisunit){
//                 if($thisunit===$unit){
//                     return;
//                 }
//             }//计算好深度先...$unit->setDepth($this->depth+1);array_push($this->units, $unit);}}function removeUnit(Unit $unit){$this->units=array_udiff($this->units, array($unit), function ($a,$b){return ($a===$b?0:1);});}}
//射手
class Archer extends Unit{function bombardStrength(){return 4;}
}
//激光塔
class LaserCannonUnit extends Unit{function bombardStrength(){return 44;}
}
//军队:由战斗单元组成
class Army extends CompositeUnit{//计算总强度function bombardStrength(){$ret=0;foreach ($this->units as $unit){$ret+=$unit->bombardStrength();}return $ret;}//移动能力,防御能力...省略
}
//运兵船:一个相似军队的单元,它具备10个战斗单元,有攻击力
class TroopCarrier extends CompositeUnit{//具备和军队差点儿相同的方法和属性function bombardStrength(){//Do something...}
}
//军队訪问者基类
abstract class ArmyVisitor{//相关方法待会写...//Army可能有多少种Unit,这里就有多少个visit方法...//方法命名规则为visit+类名//默认的visitabstract function visit(Unit $unit);function visitArcher(Archer $node){$this->visit($node);}function visitLaserCannonUnit(LaserCannonUnit $node){$this->visit($node);}function visitArmy(Army $node){$this->visit($node);}function visitTroopCarrier(TroopCarrier $node){$this->visit($node);}
}
//详细的Army訪问者类,用于转存文本
class TextDumpArmyVisitor extends ArmyVisitor{private $text="";function visit(Unit $node){$ret="";$pad=4*$node->getDepth();$ret.=sprintf("%{$pad}s","");$ret.=get_class($node).":";$ret.="bombard: ".$node->bombardStrength()."\n";$this->text.=$ret;}function getText(){return $this->text;}
}
//client实例代码
$army=new Army();
$army->addUnit(new Archer());
$army->addUnit(new LaserCannonUnit());
$textdump=new TextDumpArmyVisitor();
$army->accept($textdump);
print $textdump->getText();
/*  *  Army:bombard: 48*  Archer:bombard: 4*  LaserCannonUnit:bombard: 44*/5. 命令模式
//命令模式
//命令模式最初来源于图形化用户界面设计,但如今广泛应用于企业应用设计,特别促进了控制器(请求和分法处理)
//和领域模型(应用逻辑)的分离.说得更简单一点,命令模式有助于系统更好地进行组织,并易于扩展
//Command能够设计成接口,由于它非常easy...
//Commands/Command.php
abstract class Command{abstract function execute(CommandContext $context);
}
require_once("Command.php");
class Registry{//一个空类...static function getAccessManager(){return new AccessManager();}
}
class AccessManager{function login(){return new stdClass();}function getError(){}
}
class LoginCommand extends Command{function execute(CommandContext $context){$manager=Registry::getAccessManager();$user=$context->get('username');$user=$context->get('pass');//虚构出来的空类空方法$user_obj=$manager->login();if(is_null($user_obj)){$context->setError($manager->getError());return false;}$context->addParam("user", $user);return true;}
}
//CommandContext类用来做任务扩增用,在这儿主要功能是传递数据给Command类
class CommandContext{private $params=array();private $error="";function __construct(){$this->params=$_REQUEST;}function addParam($key,$val){$this->params[$key]=$val;}function get($key){return $this->params[$key];}function setError($error){$this->error=$error;}function getError(){return $this->error;}
}
//client代码(用于创建命令)已经调用者代码
class CommandNotFoundException extends Exception{}
//创建命令的工厂
class CommandFactory{private static $dir="Commands";//依据參数action,以及类文件存放文件夹$dir动态创建对应的$action+Command类static function getCommand($action='default'){//匹配是否出现非法字符(非字母数字下划线)if(preg_match('/\W/', $action)){throw new Exception("Illegal characters in action");}$class=ucfirst(strtolower($action)."Command");$file=self::$dir.DIRECTORY_SEPARATOR."{$class}.php";if(!file_exists($file)){throw new CommandNotFoundException("File could not be find !");}require_once("$file");if(!class_exists($class)){throw new CommandNotFoundException("Class could not be find !");}return new $class();}
}
//调用者,里面包括一个CommandContext对象实例,用于存放web请求的数据
class Controller{private $context;function __construct(){$this->context=new CommandContext();}function getContext(){return $this->context;}function process(){$cmd=CommandFactory::getCommand($this->getContext()->get('action'));if(!$cmd->execute($this->context)){//处理失败print "Faile in process!";}else{//处理成功,能够显示对应的视图层print "Success in process!";}}
}
$controller=new Controller();
$context=$controller->getContext();
$context->addParam('action', 'Login');
$context->addParam('user', 'cocos');
$context->addParam('pass', 'tiddles');
//controller运行process方法,须要不理解command的意义.
$controller->process();//Success in process

七. PHP模式设计----运行及描写叙述任务相关推荐

  1. spark任务shell运行_Spark原理与实战(七)部署模式与运行机制

    导读:Spark的运行模式指的是Spark应用程序以怎样的方式运行,单节本地点运行还是多节点集群运行,自己进行资源调度管理还是依靠别人进行调度管理.Spark提供了多种多样,灵活多变的部署模式. 作者 ...

  2. ATA接口寄存器描写叙述

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mao0514/article/details/32135815 ATA接口寄存器描写叙述 3.ATA ...

  3. BLM业务模式设计之战略控制

    说明:本文源自樊老师的线上课程<业务模式制胜,BLM战略规划七步法>第25集. 业务模式的"客户选择"和"价值主张"是从满足客户需求的角度所做的设计 ...

  4. (数据库系统概论|王珊)第七章数据库设计-第一节:数据库设计概述

    注意:此部分内容和软件工程的知识点重合较多,更多请点击[免费分享]软件工程核心知识点 本章较分散,各节导航如下 (数据库系统概论|王珊)第七章数据库设计-第二节:需求分析 (数据库系统概论|王珊)第七 ...

  5. 从壹开始微服务 [ DDD ] 之一 ║ D3模式设计初探 与 我的计划书

    缘起 哈喽大家周四好!又是开心的一天,时间过的真快,我们的 <从壹开始 .net core 2.1 + vue 2.5 >前后端分离系列共 34 篇已经完结了,当然以后肯定还会有更新和修改 ...

  6. 模式设计概述:代理者模式

    分布式系统模式 分布式相关的模式设计有大概三种模式,分布式系统与集中式系统相比需要完全不同的软件.管道和过滤器模式,微核和代理者模式. 代理者模式 代理者模式体系结构的强制条件是 组件应该能够访问其他 ...

  7. mongodb数据合并设计_「时间序列数据」和MongoDB(二)-模式设计最佳实践

    在上一篇博客文章时间序列数据与MongoDB:第一部分-简介中,我们介绍了时间序列数据的概念,然后介绍了一些可以用于帮助收集时间序列应用程序需求的发现问题.对这些问题的回答有助于指导支持大容量生产应用 ...

  8. 数据库系统概念总结:第七章 数据库设计和E-R模型

    周末无事水文章,期末备考的总结资料 第七章 数据库设计和E-R模型 7.1 设计过程概览 7.1.1 设计阶段 需要完整地刻画未来数据库用户的数据需求 选择数据模型,并采用所选数据模型的概念将这些需求 ...

  9. 反模式设计_设计模式:模式或反模式,这就是问题

    反模式设计 我最近遇到了Wiki页面" Anti-pattern" ,其中包含详尽的反模式列表. 其中一些对我来说很明显. 他们中的一些让我想了一下,其他的让我想了更多. 然后,我 ...

最新文章

  1. 一个非常好用的 Python 魔法库
  2. iOS 进阶之底层原理一OC对象原理alloc做了什么
  3. Linux压缩解压命令合集
  4. react实战课程_在使用React一年后,我学到的最重要的课程
  5. 修改计算机属性中的内存大小_Python 类属性的动态特点
  6. 谈一谈Java 中 1000==1000 为false,而100==100 为true?
  7. 高并发锁Lock的详细使用
  8. amend用法 git 信息_Git 高级用法,你用过哪些了
  9. js常用方法之Array对象方法扩展
  10. VJ—蟠桃记(C语言)
  11. Linux之父炮轰 “全球最大同性恋网站” GitHub:Merge制造了毫无用处的垃圾信息!...
  12. matlab音乐简谱程序,简谱书写程序(Music Writer)
  13. (转)TCP注册端口号大全
  14. 概念学习(Concept learning)
  15. 登月计划 [扩展回旋阿姆斯特朗算法]
  16. 中国式危机公关9加1策略(第十三章 建立系统实用的危机管理机制)
  17. robotstudio机器人应用实践(码垛搬运工作站)
  18. 董卫凤:不服输的华丽转身(二)
  19. 魔兽DOTA高玩的自述
  20. From detailed models to formal spiking neurons

热门文章

  1. 看完这篇AI算法和笔记,让面试官刮目相看没问题了 | 基于深度学习和传统算法的人体姿态估计...
  2. ubuntu练习打字,Ubuntu装mac主题
  3. 项目回顾之三:练字秀【已开源】
  4. TP6 重定向redirec使用场景
  5. javascript获取select 的id与值
  6. tenth day for learning
  7. VMware 与戴尔正式“分手”
  8. 麦肯锡消费报告:中国的数字化消费者正在创造海量数据池
  9. python36.lib如何区分release debug_从sou安装python3.6.3后lsb_release不工作
  10. 低成本高性能 USB2.0 扩展器,可通过 USB 电缆提供信号传输扩展