软件开发中涉及到的设计模式很多,这里重点讨论工作中常见的一些设计模式,围绕王者荣耀中的场景进行展开。
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());
}
?>
策略模式组成
- 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用。
一句话理解
你输入的参数最后被程序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());
}
?>
一句话理解
你在框架基类定义了很多公共方法,给大家继承使用。
工厂模式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());
?>
注意:代码这样写肯定不简洁,应该结合策略模式写。这里为了便于理解就这样写了。
适配器精髓
利用继承,暴露相同接口。
适配器应用
电源适配,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();
单例模式组成(三私一公)
- 私有的静态属性 (保存类的实例)
- 私有的构造方法 (防止类外实例化)
- 私有的克隆方法 (防止通过克隆生成对象)
- 公有的静态方法 (调取这个类相当一个接口 )
单例模式精髓
类只被new一次
单例模式应用
搜索了很多系统代码,只有在数据库连接时有用到。个人觉得原因如下:
1:数据库连接消耗资源,一次请求建立多次连接,数据库扛不住。单例模式可以做到一次请求只会对数据库建立一次连接,而不是多次。这样不容易出现 too many connections情况。
2:单例模式 三私一公 写法相对麻烦,除了数据库连接外,效果不明显。
5:外观模式
外观模式应用
优秀文章:外观模式(简单,不写了)
外观模式精髓
一个方法集成了多个动作。
外观模式应用
妲己蹲草丛,调用二技能,大招,一技能收割。就可以封装个妲己蹲草丛的方法。
删除商户,需要删除店铺,删除菜品,删除点评(逻辑删除)。就需要封装删除商户的方法。
6:其他
这些设计模式都是围绕设计原则展开:
开闭原则:对拓展开放,对修改关闭。即:尽量在不修改原有代码的情况下进行拓展。(策略模式就是典型)
单一职责原则:一个类只负责一个功能领域中相应的职责。(单例模式就是典型)
......更多原则见:设计模式之设计模式六大原则