您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 前段时间看到有人用魔兽来解释设计模式
使市场前段时间看到有人用魔兽来解释设计模式,感觉很有意思,于是我把它改了改,又添加了些设计模式内容,今天发出来。有些地方借鉴了前人的内容,没有注明,请前人不要见怪啊。这里用大家感兴趣的魔兽3来讨论PHP的几种常见的设计模式:单件模式、策略模式、工厂模式、观察者模式。今天就讲这四个吧,以后继续。这些设计模式,都是针对面向对象来说的,所以都用PHP5,另外在这里我想说的是PHP4从2008年8月8日(我记得是和北京奥运会同一天,没查证,呵呵)的时候官方就发了最后一个PHP4的补丁,这意味这PHP4的时代已经终结,所以,我建议大家现在就别理PHP4吧,就以PHP5来说吧。一、单件模式:问题的提出:某些应用程序资源是独占的,因为有且只有一个此类型的资源。例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更是如此。问题的解决:那么下面我们就开始玩魔兽吧。首先双击war3.exe,这时候就开始运行魔兽了。我们用代码来实现吧。?phpclassWar3{publicfunction__construct(){echoWar3isRunning.,br/;}}$war=newWar3();运行!很好,输出War3isRunning.我们已经可以开始游戏了,但是,如果我在代码末尾再加入$war2=newWar3();$war3=newWar3();会怎么样呢?我们试试,输出结果:War3isRunning.War3isRunning.War3isRunning.完了,如果不小心双击了两次就开了3个魔兽,那如果再双击几次,那电脑肯定爆掉。。。我们还是来想想解决方法吧。既然我们不能这么随意的就把这个类实例化了,那么我们就把构造函数改成私有方法。classWar3{privatefunction__construct(){echoWar3isRunning.,br/;}}可是私有变量外部是无法访问的,这样以来,我们就连一个都打不开了啊。别急,我们再给他加一个不用通过实例化,外部也能访问的函数,那就是静态函数,classWar3{privatefunction__construct(){echoWar3isRunning.,br/;}publicstaticfunctionrunWar(){}}通过这个静态的方法runWar()我们来控制类War3的实例化,那么还缺上一个标识,我们再创建一个标识,通过这个标识来表示我们的类是否已经实例化,如果实例化,直接返回句柄就行了。把类修改成classWar3{protectedstatic$_instance=null;privatefunction__construct(){echoWar3isRunning.,br/;}publicstaticfunctionrunWar(){if(null===self::$_instance){self::$_instance=newself();}returnself::$_instance;}}当然,我们运行魔兽时的实例化也要换种方法,就通过$war=War3::runWar();就能开始玩魔兽了,好了,下面把完整的代码附上来:?phpclassWar3{protectedstatic$_instance=null;privatefunction__construct(){echoWar3isRunning.,br/;}publicstaticfunctionrunWar(){if(null===self::$_instance){self::$_instance=newself();}returnself::$_instance;}}$war=War3::runWar();$war2=War3::runWar();$war3=War3::runWar();运行一下,结果是:War3isRunning.太好了,我双击了这么多次,也就只运行了一个魔兽,现在随便你怎么打开,机子都不会爆掉了。这就是传说中的单价模式,主要用于一些很占资源的而且实例仅有一个实例就够用的东西,比如,zendframework中的Zend_Controller_Front前端控制器,就是采用单价模式来设计的,大家有兴趣的话可以看看那个。二、策略模式:问题的提出:在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分——一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。问题的解决:呵呵,不讲那么复杂,刚才魔兽好不容易打开了,我们还是玩魔兽好了。下面我们选battle,哇好多种族啊,有人族(Human),兽族(ORC),暗夜精灵族(NighyElf),不死族(Undead)。我选精灵族(NighyElf),再选一个精灵族和两个兽族(ORC),一个兽族和我是一家的,另一个精灵族和兽族是另一家的。每一个玩家在进入游戏后都会得到一些资源,如一个大厅,五个小精灵(苦工)和一个矿山。这些可以称为是初始化的一些东西,这里我们就可以用到策略模式来封装这些初始化。进入正题,首先我们来构建一个玩家类:?phpclassplayer{//玩家名字protected$_name;//种族protected$_race;//队伍protected$army;//建筑protected$building;//人口protected$population;//黄金protected$gold;//木材protected$wood;//构造函数,设定所属种族publicfunction__construct($race){$this-race=$race;}//__get()方法用来获取保护属性privatefunction__get($property_name){if(isset($this-$property_name)){return($this-$property_name);}else{return(NULL);}}//__set()方法用来设置保护属性privatefunction__set($property_name,$value){$this-$property_name=$value;}}接着,我们再建一个玩家初始化的接口,?phpinterfaceinitialPlayer{//制造初始化的部队publicfunctiongiveArmy($player);//制造初始化的建筑publicfunctiongiveBuilding($player);//初始化资源publicfunctiongiveSource($player);}好了,到这里我们就该对这个接口来实现了,为了方便,我只选了两个种族,就只写这两个种族的初始化了:首先是精灵族:?phpclassNighyElfInitialimplementsinitialPlayer{//制造初始化的部队publicfunctiongiveArmy($player){//五个小精灵for($i=0;$i=5;$i++){$creator=newCreatArms();//这个是创建部队类,在后面得工厂模式中会用到,这里我就不多说了$player-army[]=$creator-Creat('Wisp','./Arms/');}}//制造初始化的建筑publicfunctiongiveBuilding($player){$creator=newCreatBuildings();//一个基地$player-building[]=$creator-Creat('TownHall','./Buildings/');//一个矿场$player-building[]=$creator-Creat('Mine','./Buildings/');}//初始化人口上限publicfunctiongiveSource($player){$player-population=10;$player-gold=1000;$player-wood=100;}}接下来是兽族:?phpclassORCInitialimplementsinitialPlayer{//制造初始化的部队publicfunctiongiveArmy($player){//五个苦工for($i=0;$i=5;$i++){$creator=newCreatArms();//这个是创建部队类,在后面得工厂模式中会用到,这里我就不多说了$player-army[]=$creator-Creat('Peon','./Arms/');}}//制造初始化的建筑publicfunctiongiveBuilding($player){$creator=newCreatBuildings();//一个基地$player-building[]=$creator-Creat('TownHall','./Buildings/');//一个矿场$player-building[]=$creator-Creat('Mine','./Buildings/');}//初始化人口上限publicfunctiongiveSource($player){$player-population=10;$player-gold=1000;$player-wood=100;}}好了,到这里初始化代码就写好了,现在还差一个控制这些初始化得类,也就是封装他们:?phpclassinitialController{//构造函数,参数为玩家的数组publicfunction__construct($playerArray){foreach($playerArrayas$player){switch($player-race){case'NighyElf':$initialController=newNighyElfInitial();break;case'ORC':$initialController=newORCInitial();break;}$initialController-giveArmy($player);$initialController-giveBuilding($player);$initialController-giveSupply($player);}}}最后就是简单这么一调用,就OK:?php//有两个精灵族两个兽族$playerArray=array(newplayer('NighyElf'),newplayer('NighyElf'),newplayer('ORC'),newplayer('ORC'));//进行初始化工作$initialController=newinitialController($playerArray);这就是策略模式,他将不同情况下的算法封装在一起。Zendframework中的Zend_Application_Resource就是用策略模式来设计的。三、工厂模式:问题的提出:最初在设计模式一书中,许多设计模式都鼓励使用松散耦合。要理解这个概念,让我们最好谈一下许多开发人员从事大型系统的艰苦历程。在更改一个代码片段时,就会发生问题,系统其他部分——您曾认为完全不相关的部分中也有可能出现级联破坏。该问题在于紧密耦合。系统某个部分中的函数和类严重依赖于系统的其他部分中函数和类的行为和结构。您需要一组模式,使这些类能够相互通信,但不希望将它们紧密绑定在一起,以避免出现联锁。在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的
本文标题:前段时间看到有人用魔兽来解释设计模式
链接地址:https://www.777doc.com/doc-727825 .html