七. PHP模式设计----执行及描述任务
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); //每一个对象都有一个唯一的key function 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){ //模拟返回true return 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)); } } //客户端示例代码 $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"; } } } /*RegexpMarker response:five: well done response:four: never mind MatchMarker response:five: never mind response:four: never mind MarkLogicMarker response:five: well done response: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"; } } //客户端代码有一点点改变... $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+类名 //默认的visit abstract 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; } } //客户端实例代码 $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可以设计成接口,因为它很简单... //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; } } //客户端代码(用于创建命令)已经调用者代码 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

恐怖走廊是模拟山羊3之中的一个任务,这个任务要怎么样才能够去完成呢,掌握到详细的过关方式和对应的流程,能够完成这个任务的相应挑战,下面就为大家带来模拟山羊3恐怖走廊攻略,了解相关的信息。模拟山羊3恐怖走廊攻略1、首先需要玩家前往地图左上角的寂静岭处。2、在这里可以看到一个屋顶上写着RESTSTOP的房子,玩家需要操作山羊进入这个房子。3、进入房间之后,我们首先向前直走,随后向右转,在这里尽头有一扇门,我们直接从这里进去。4、进入之后同样是先向前走随后右转,在这里走到门前门会关上,我们需要回头找到

模拟山羊3是有着经典模拟玩法的游戏,可让玩家充分体验到休闲动作类操作模拟的乐趣,游戏中还拥有很多特色任务的精彩,其中模拟山羊3帝陵任务是需要玩家找寻到钟塔上的三个钟并操作的,一些玩家还不清楚要怎么弄,下面带来模拟山羊3帝陵任务攻略流程分享!模拟山羊3帝陵任务攻略流程按照顺序敲击钟即可。详细步骤拓展1、首先玩家需要打开地图去到雾丘公墓。2、然后上到钟楼上,里面会有着三个钟。3、接着按照从大到小的顺序,按照222312312熟悉怒敲击。4、完成敲击后即可完成任务,并打开大门获得光剑。

要自动化任务和管理多个系统,任务计划软件是您武器库中的宝贵工具,尤其是对于系统管理员而言。Windows任务计划程序完美地完成了这项工作,但最近许多人报告说操作员拒绝了请求错误。该问题存在于操作系统的所有迭代中,即使已经广泛报告和涵盖,也没有有效的解决方案。继续阅读以找到真正对其他人有用的内容!操作员或管理员拒绝了任务计划程序0x800710e0中的请求是什么?任务计划程序允许在没有用户输入的情况下自动执行各种任务和应用程序。您可以使用它来安排和组织特定应用程序、配置自动通知、帮助传递消息等。它

营救史蒂夫是模拟山羊3中的一个独特任务,具体需要怎么做才能够完成呢,这个任务比较简单,但是我们需要注意不要理解错意思,下面就为大家带来模拟山羊3营救史蒂夫任务攻略,能够更好的完成相关的任务。模拟山羊3营救史蒂夫任务攻略1、首先来到地图中右下角的温泉。2、在来到温泉边上之后就可以触发营救史蒂夫的这个任务。3、注意在温泉里有个男人,虽然他也叫史蒂夫,但是并不是本次任务的目标。4、在这个温泉里找到一条叫史蒂夫的鱼,并且将其带上岸,即可完成这个任务。

抖音作为当下最受欢迎的社交媒体平台之一,吸引了大量用户参与其中。在抖音上,有很多粉丝团任务可供用户完成,从而获得一定的奖励和福利。那么,抖音粉丝团任务在哪里可以找到呢?一、抖音粉丝团任务在哪里看?为了找到抖音粉丝团任务,你需要访问抖音的个人主页。在主页上,你会看到一个名为“粉丝团”的选项。点击这个选项,你就可以浏览你所加入的粉丝团和相关任务。在粉丝团任务栏目中,你会看到各种不同类型的任务,如点赞、评论、分享、转发等。每个任务都有对应的奖励和要求,一般来说,完成任务后会获得一定数量的金币或者经验值

epc+o模式就是指设计、采购等等为一体的总承包框架,它是在epc里面引申出来的一些运营环节;即在建设期内时,总承包商除了要去承担传统意义上的设计任务以外,还要去包揽在运营期内的所有维护任务。该模式可以极大程度提高许多项目的运营效率,也可以迅速降低运营成本。

如何在Windows11和Windows10中暂停任务管理器进程更新按CTRL+窗口键+删除打开任务管理器。默认情况下,任务管理器将打开“进程”窗口。正如您在此处看到的,所有应用程序都在无休止地移动,当您想要选择它们时,可能很难将它们指向下方。因此,按CTRL并按住它,这将暂停任务管理器。您仍然可以选择应用程序,甚至可以向下滚动,但您必须始终按住CTRL按钮。

实现任务通用是深度学习基础模型研究的核心问题,也是近期大模型方向的主要关注点之一。然而,在时间序列领域,各类分析任务的差别较大,既有需要细粒度建模的预测任务,也有需要提取高层语义信息的分类任务。如何构建统一的深度基础模型高效地完成各类时序分析任务,此前尚未有成型方案。为此,来自清华大学软件学院的团队围绕时序变化建模这一基本问题展开研究,提出了任务通用的时序基础模型TimesNet,论文被ICLR 2023接收。作者列表:吴海旭*,胡腾戈*,刘雍*,周航,王建民,龙明盛链接:https://ope


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),