从王者荣耀谈设计模式
软件开发中涉及到的设计模式很多,这里重点讨论工作中常见的一些设计模式,围绕王者荣耀中的场景进行展开。
1:策略模式
策略模式demo
<?php //1:抽象策略接口:王者荣耀 abstract class kingGlory{ abstract function showTime(); } //2:具体策略角色 //鲁班 class luban extends kingGlory{ public function showTime(){ echo \'猥琐发育,躲坦克后面\'; } } //王昭君 class wangzhaojun extends kingGlory{ public function showTime(){ echo \'冰杖一技能减速,二技能冰住人才开大\'; } } //东皇太一 class dragon extends kingGlory{ public function showTime(){ echo \'保护射手,把大留给对方刺客\'; } } //小乔 class xiaoqiao extends kingGlory{ public function showTime(){ echo \'二技能没让对方起飞,不随便开大入场\'; } } //以后再上新什么角色,在这里扩展方法就好。 //3:环境角色:王者峡谷 class canyonKingGlory{ private $canyonKingGlory; //获取具体策略 public function getKingGlory($hero){ try{ $strategyReflection = new ReflectionClass($hero); $this->canyonKingGlory = $strategyReflection->newInstance(); }catch(Exception $e){ throw $e; } } function showTime(){ $this->canyonKingGlory->showTime(); } } try{ $hero = empty($_GET[\'hero\']) ? \'\' : trim($_GET[\'hero\']); $canyonKingGlory = new canyonKingGlory(); $canyonKingGlory->getKingGlory($hero); $canyonKingGlory->showTime(); }catch(Exception $e){ print_r($e->getMessage()); } ?>
View Code
策略模式组成
- 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用。
一句话理解
你输入的参数最后被程序new 成了对象。如:localhost/kingGlory?hero=luban 程序new luban。
策略模式应用
见和工厂模式pk的应用
2:工厂模式
工厂模式demo
<?php //1:王者荣耀 abstract class kingGlory{ abstract function showTime(); //击败蓝buff public function killBlueBuff(){ echo \'减cd\'; } //击败主宰 public function killDominate(){ echo \'加攻击力;派出小龙\'; } } //鲁班 class luban extends kingGlory{ public function showTime(){ echo \'猥琐发育,躲坦克后面\'; } public function secondSkill(){ $ability = $this->killDominate();//等等 } } //王昭君 class wangzhaojun extends kingGlory{ public function showTime(){ echo \'冰杖一技能减速,二技能冰住人才开大\'; } } //王者峡谷 class canyonKingGlory{ private $canyonKingGlory; public function __call($name, $args) { $this->canyonKingGlory->$name(); } //获取具体策略 public function getKingGlory($hero){ try{ $strategyReflection = new ReflectionClass($hero); $this->canyonKingGlory = $strategyReflection->newInstance(); }catch(Exception $e){ throw $e; } } } try{ $hero = empty($_GET[\'hero\']) ? \'\' : trim($_GET[\'hero\']); $canyonKingGlory = new canyonKingGlory(); $canyonKingGlory->getKingGlory($hero); $canyonKingGlory->secondSkill(); }catch(Exception $e){ print_r($e->getMessage()); } ?> //http://localhost/single.php?hero=luban
View Code
一句话理解
你在框架基类定义了很多公共方法,给大家继承使用。
工厂模式pk策略模式
这两个模式很相似,见上面demo就会有感觉。而且两个模式通常会嵌套在一起使用!
工厂模式:你在框架基类定义了很多公共方法,给大家继承使用。
策略模式:你在框架写了很多继承框架基类的业务代码。
工厂模式pk策略模式应用场景
在王者峡谷,新来的英雄继承峡谷规则:闪现可以穿墙,拿蓝bug减cd , 抢龙有金币经验等…(这就是工厂模式)
新英雄是隐身,是飞天,是同归于尽,是死后重生…可以自由发挥设计…新加一个类就行,而不是switch case 一个个加。(这就是策略模式)
代码中,一次请求开始要进行 ip检查,登录检查,xss注入转义,日志埋点…这就是工厂模式
开发业务的同学在业务代码里搞物流,搞装修,搞外卖,搞海淘…这就是策略模式
3:适配器模式
适配器demo
<?php //王者荣耀行为基类 abstract class kingGloryAct{ //过草丛 public abstract function grassBushes(); //过草丛公共方法 public function grassBushesCommom(){ return \'过草丛隐身\'; } } //鲁班 class luban extends kingGloryAct{ public function grassBushes(){ $effect[] = $this->grassBushesCommom(); return $effect; } } //东皇太一 ;之前有bug 暴露它的球球 class dragon extends kingGloryAct{ public function grassBushes(){ $effect[] = $this->grassBushesCommom(); $effect[] = \'暴露球球\'; return $effect; } } //成吉思汗 class erha extends kingGloryAct{ public function grassBushes(){ $effect[] = $this->grassBushesCommom(); $effect[] = \'加速\'; return $effect; } } echo \'<pre/>\'; $luban = new luban; print_r($luban->grassBushes()); $dragon = new dragon; print_r($dragon->grassBushes()); $erha = new erha; print_r($erha->grassBushes()); ?>
View Code
注意:代码这样写肯定不简洁,应该结合策略模式写。这里为了便于理解就这样写了。
适配器精髓
利用继承,暴露相同接口。
适配器应用
电源适配,usb适配
典型项目:openapi;微信登录 php,java,C,.net 对接….
4:单例模式
单例模式demo
class singleton{ //1:创建静态私有的变量保存该类对象 static private $instance; public $config; //2:一个类在一次请求中只能有一个对象 :私有防止被直接实例化; private function __construct( $config ){ $this->config = $config; } //3:该类提供静态的公有的函数用于创建或获取它本身的静态私有对象。 public static function getInstance($config){ //判断$instance是否是singleton的对象 没有则创建 if (!self::$instance instanceof self) { self::$instance = new self($config); } return self::$instance; } //4:防止克隆对象 private function __clone(){ } public function getConfig(){ print_r($this->config); } } //单例,一次请求只会实例化一次。 $singleton = singleton::getInstance( \'妲己\' );// 妲己 $singleton->getConfig(); $singleton = singleton::getInstance( \'小乔\' );// 妲己 $singleton->getConfig();
View Code
单例模式组成(三私一公)
- 私有的静态属性 (保存类的实例)
- 私有的构造方法 (防止类外实例化)
- 私有的克隆方法 (防止通过克隆生成对象)
- 公有的静态方法 (调取这个类相当一个接口 )
单例模式精髓
类只被new一次
单例模式应用
搜索了很多系统代码,只有在数据库连接时有用到。个人觉得原因如下:
1:数据库连接消耗资源,一次请求建立多次连接,数据库扛不住。单例模式可以做到一次请求只会对数据库建立一次连接,而不是多次。这样不容易出现 too many connections情况。
2:单例模式 三私一公 写法相对麻烦,除了数据库连接外,效果不明显。
5:外观模式
外观模式应用
优秀文章:外观模式(简单,不写了)
外观模式精髓
一个方法集成了多个动作。
外观模式应用
妲己蹲草丛,调用二技能,大招,一技能收割。就可以封装个妲己蹲草丛的方法。
删除商户,需要删除店铺,删除菜品,删除点评(逻辑删除)。就需要封装删除商户的方法。
6:其他
这些设计模式都是围绕设计原则展开:
开闭原则:对拓展开放,对修改关闭。即:尽量在不修改原有代码的情况下进行拓展。(策略模式就是典型)
单一职责原则:一个类只负责一个功能领域中相应的职责。(单例模式就是典型)
……更多原则见:设计模式之设计模式六大原则
版权声明:本文为adair123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。